Сетевое подключение NSNotification для OSX? - PullRequest
3 голосов
/ 26 мая 2010

Мне просто нужно иметь уведомление при назначении действительного IP-адреса. Я пытался опросить через SCReachability, но это кажется неэффективным.

Есть предложения? Кажется, это должно быть просто, но я несколько часов пытался заставить что-то работать

Ответы [ 2 ]

10 голосов
/ 06 января 2011

Я знаю, что это немного устарело, но выбранный ответ не идеален.

API SCReachability может использоваться для определения доступности определенного хоста. Если все, что вы хотите знать, - это когда назначен действительный IP-адрес (а не жизнеспособный маршрут к целевому IP-адресу), вам следует вместо этого взглянуть на API SCDynamicStore *. Эти функции позволяют подписаться на хранилище конфигурации системы для уведомления при изменении определенных значений. Таким образом, для уведомления об изменении адреса IPv4 на любом интерфейсе вы должны сделать следующее (проверка ошибок удалена для удобства чтения)

  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);

Вам нужно будет реализовать функцию scCallback, которая будет вызываться при каждом изменении. Также вам нужно будет вызвать CFRunLoopRun где-нибудь, чтобы заставить код работать.

1 голос
/ 28 мая 2010

Вам не нужно опрашивать с SCNetworkReachability. Вы регистрируете обратный вызов, и система вызывает обратный вызов при изменении состояния сети. Это не неэффективно.

См. Пример кода Apple Достижимость , который показывает, как интегрировать его в приложение Objective-C. Код для iPhone, но я думаю, Reachability.{m,h} должно работать на OS X.

(см. Пример кода Apple SimpleReach . Ему пять лет, но он должен работать.)

...