简体   繁体   中英

Notification when wifi connected (OS X)

I need a notification from the system when airport is connecting to an ap. Is there any possibility to do that with the SystemConfiguration framework? I have problems to understand the systemconfigurations api documentation.

You are on the right track with the SystemConfiguration network, which offers the SCNetworkReachability set of functions. You could try using

SCNetworkReachabilitySetCallback

to set a callback which will be called when the reachability changes; and

SCNetworkReachabilityScheduleWithRunLoop

to schedule the reachability check within the run loop

Or you might try using a reachability framework (both for MacOS and iOS) which is built on top of the SystemConfiguration framework to make things even easier (higher-level).

If you want to go the SystemConfiguration way, this is how you check for present reachability and install the callback to be notified of changes ( source ):

- (void)checkReachability {
  NSString *server = [[NSUserDefaults standardUserDefaults] stringForKey:@"NCIDServer"];

  if (server == nil) {
    ncid_message_callback(self, [NSLocalizedString(@"No caller ID server was specified.", nil) UTF8String]);
    return;
  }

  const char *serverName = [[[server componentsSeparatedByString:@":"] objectAtIndex:0] UTF8String];
  SCNetworkReachabilityContext context = {0, (void *)self, NULL, NULL, NULL};
  networkReachability = SCNetworkReachabilityCreateWithName(NULL, serverName);

  if (networkReachability == NULL)
    goto fail;

  // If reachability information is available now, we don't get a callback later
  SCNetworkConnectionFlags flags;

  if (SCNetworkReachabilityGetFlags(networkReachability, &flags))
    networkReachabilityCallback(networkReachability, flags, self);

  if (!SCNetworkReachabilitySetCallback(networkReachability, networkReachabilityCallback, &context))
    goto fail;

  if (!SCNetworkReachabilityScheduleWithRunLoop(networkReachability, [[NSRunLoop currentRunLoop] getCFRunLoop], kCFRunLoopCommonModes))
     goto fail;
  return;

fail:
  if (networkReachability != NULL)
    CFRelease(networkReachability);

  networkReachability = NULL; //-- ivar representing current reachability

}

And this is a sample of the callback:

static void networkReachabilityCallback(SCNetworkReachabilityRef target,
                SCNetworkConnectionFlags flags,
                void *object) {
  // Observed flags:
  // - nearly gone: kSCNetworkFlagsReachable alone (ignored)
  // - gone: kSCNetworkFlagsTransientConnection | kSCNetworkFlagsReachable | kSCNetworkFlagsConnectionRequired
  // - connected: kSCNetworkFlagsIsDirect | kSCNetworkFlagsReachable

  if (networkReachability == NULL)
    return;

  if ((flags & kSCNetworkFlagsReachable) && !(flags & kSCNetworkFlagsConnectionRequired))    {

    if (isReachable) // typically receive a reachable message ~20ms before the unreachable one
    return;

    isReachable = YES;
    ncid_network_kill();
    [NSThread detachNewThreadSelector:@selector(runThread:) toTarget:object withObject:nil];

  } else {
    isReachable = NO;
    ncid_network_kill();
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM