2

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.

Machavity
  • 30,841
  • 27
  • 92
  • 100
dnlkng
  • 829
  • 1
  • 10
  • 16

2 Answers2

5

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();
  }
}
sergio
  • 68,819
  • 11
  • 102
  • 123
0

You need to use Apple's Reachability class for this. http://developer.apple.com/library/ios/#samplecode/Reachability/Listings/Classes_Reachability_m.html#//apple_ref/doc/uid/DTS40007324-Classes_Reachability_m-DontLinkElementID_6

You can check this thread for how to use this class-

How do I receive notifications that the connection has changed type (3G, Edge, Wifi, GPRS)

Community
  • 1
  • 1
rishi
  • 11,779
  • 4
  • 40
  • 59