Search code examples
ioscocoanetwork-programmingreachabilitysystem-configuration

Internet connection on Mac and iOS


I'm currently writing some code to determine if a network request is possible on either Mac or iOS.

Before I get told to look at the Reachability classes provided by Apple, I just want to point out that even by using them I'm getting the same results. So, instead, I thought I'd write my own as it's literately all I need.

I've initiated a reachability object exactly like Apple:

+ (Reachability*) reachabilityForInternetConnection;
{
    struct sockaddr_in zeroAddress;
    bzero(&zeroAddress, sizeof(zeroAddress));
    zeroAddress.sin_len = sizeof(zeroAddress);
    zeroAddress.sin_family = AF_INET;
    return [self reachabilityWithAddress: &zeroAddress];
}

Then calling [networkStatusForFlags:flags] (or its equviliant in my code), I have the following:

NSLog(@"Reachability Flag Status: %c%c %c%c%c%c%c%c%c\n",
      (flags & kSCNetworkReachabilityFlagsIsWWAN)               ? 'W' : '-',
      (flags & kSCNetworkReachabilityFlagsReachable)            ? 'R' : '-',

      (flags & kSCNetworkReachabilityFlagsTransientConnection)  ? 't' : '-',
      (flags & kSCNetworkReachabilityFlagsConnectionRequired)   ? 'c' : '-',
      (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic)  ? 'C' : '-',
      (flags & kSCNetworkReachabilityFlagsInterventionRequired) ? 'i' : '-',
      (flags & kSCNetworkReachabilityFlagsConnectionOnDemand)   ? 'D' : '-',
      (flags & kSCNetworkReachabilityFlagsIsLocalAddress)       ? 'l' : '-',
      (flags & kSCNetworkReachabilityFlagsIsDirect)             ? 'd' : '-'
      );

BOOL thereIsInternetAccess = NO;

if ((flags & kSCNetworkReachabilityFlagsReachable) != 0 && (flags & kSCNetworkReachabilityFlagsConnectionRequired) == 0)
{
    thereIsInternetAccess = YES;
}
else
{
    thereIsInternetAccess = NO;
}

Regardless of if my Mac's Wifi is on or off, I'm getting the following outputted to the console Reachability Flag Status: -R -----l- which to me indicates that the internet is present (due to R being flagged)

Am I missing something? Any help would be appreciated greatly.

NOTE: I'm using the iOS Simulator. Don't think that should matter though.


Solution

  • The iOS Simulator doesn't work as you'd expect it to.

    Using the System Configuration framework for network reachability does notify when the Mac's network status has been updated using the registered call back (SCNetworkReachabilitySetCallback). However, from my testing it appears the flags are not returned back correctly every time. Using the same code on a Mac with a mac app target, or on an iOS Device, the code runs with the expected results.

    Yet another reason why the simulator should never be the only testing means for your app.