2010-05-26 5 views
3

J'ai simplement besoin d'un message de notification lorsqu'une adresse IP valide est assignée. J'ai essayé d'interroger via SCReachability, mais cela semble être inefficace.Connexion réseau NSNotification pour OSX?

Des suggestions? Cela semble être simple, mais j'ai lutté pendant plusieurs heures pour que tout fonctionne.

Répondre

8

Je sais que c'est un peu vieux, mais la la réponse choisie n'est pas idéale.

L'API SCReachability peut être utilisée pour savoir quand un hôte particulier est accessible. Si tout ce que vous voulez savoir est quand une adresse IP valide est assignée (plutôt qu'une route viable à une adresse IP cible) alors vous devriez regarder les API SCDynamicStore * à la place. Ces fonctions vous permettent de vous abonner au magasin de configuration du système pour recevoir des notifications lorsque certaines valeurs changent. Ainsi, pour la notification en cas de changement d'adresse IPv4 sur toute interface que vous effectuez les opérations suivantes (vérification d'erreurs supprimées pour une meilleure lisibilité)

SCDynamicStoreRef dynStore; 

    SCDynamicStoreContext context = {0, NULL, NULL, NULL, NULL}; 

    dynStore = SCDynamicStoreCreate(kCFAllocatorDefault, 
            CFBundleGetIdentifier(CFBundleGetMainBundle()), 
            scCallback, 
            &context); 

    const CFStringRef keys[3] = { 
     CFSTR("State:/Network/Interface/.*/IPv4") 
    }; 
    CFArrayRef watchedKeys = CFArrayCreate(kCFAllocatorDefault, 
             (const void **)keys, 
             1, 
             &kCFTypeArrayCallBacks); 
    if (!SCDynamicStoreSetNotificationKeys(dynStore, 
             NULL, 
             watchedKeys)) 
    { 
     CFRelease(watchedKeys); 
     fprintf(stderr, "SCDynamicStoreSetNotificationKeys() failed: %s", SCErrorString(SCError())); 
     CFRelease(dynStore); 
     dynStore = NULL; 

     return -1; 
    } 
    CFRelease(watchedKeys); 

    rlSrc = SCDynamicStoreCreateRunLoopSource(kCFAllocatorDefault, dynStore, 0); 
    CFRunLoopAddSource(CFRunLoopGetCurrent(), rlSrc, kCFRunLoopDefaultMode); 
    CFRelease(rlSrc); 

Vous devrez imlement la fonction scCallback qui sera appelée à chaque fois qu'il ya un changement. De plus, vous devrez appeler CFRunLoopRun quelque part pour lancer le code.

1

Vous n'avez pas à interroger avec SCNetworkReachability. Vous enregistrez le rappel et le système appelle le rappel lorsque l'état du réseau change. Ce n'est pas inefficace.

Voir l'exemple de code Reachability d'Apple qui montre comment l'intégrer dans une application Objective-C. Le code est pour l'iPhone, mais je pense que Reachability.{m,h} devrait fonctionner sur Mac OS X.

(Voir le code exemple d'Apple SimpleReach. Il est de cinq ans, mais devrait fonctionner.)

+0

Je dois admettre - je suis exceptionnellement confus à cet exemple. Je suis très nouveau à Cocoa, et je ne suis pas sûr de comprendre comment intégrer cet exemple C dans mon programme ObjC. Astuces? –

+0

Trouvé un exemple de code plus récent chez Apple. Voir la nouvelle réponse – Yuji