CFHipsterRef Low-Level Programming on iOS & Mac OS X

Determining Network Reachability Synchronously

Like any networking, establishing reachability should not be done synchronously.

@import SystemConfiguration;

SCNetworkReachabilityRef networkReachability = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault,
[@"www.apple.com" UTF8String]);

SCNetworkReachabilityFlags flags = SCNetworkReachabilityGetFlags(networkReachability, &flags);

// Use flags to determine reachability
CFRelease(networkReachability);

SCNetworkReachabilityRef is the data type responsible for determining network reachability. It can be created by either passing host name, like in the previous example, or a sockaddr address:

BOOL ignoresAdHocWiFi = NO;

struct sockaddr_in ipAddress;
bzero(&ipAddress, sizeof(ipAddress));
ipAddress.sin_len = sizeof(ipAddress);
ipAddress.sin_family = AF_INET;
ipAddress.sin_addr.s_addr = htonl(ignoresAdHocWiFi ? INADDR_ANY : IN_LINKLOCALNETNUM);

SCNetworkReachabilityRef networkReachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (struct sockaddr *)ipAddress);
BOOL isReachable =
((flags & kSCNetworkReachabilityFlagsReachable) != 0);

BOOL needsConnection =
((flags & kSCNetworkReachabilityFlagsConnectionRequired) != 0);

BOOL canConnectionAutomatically =
(((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) ||
((flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0));

BOOL canConnectWithoutUserInteraction = (canConnectionAutomatically &&
(flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0);

BOOL isNetworkReachable = (isReachable &&
(!needsConnection || canConnectWithoutUserInteraction));
if (isNetworkReachable == NO)
{
    // Not Reachable
}
#if TARGET_OS_IPHONE
else if ((flags & kSCNetworkReachabilityFlagsIsWWAN) != 0)
{
    // Reachable via WWAN
}
#endif
else
{
    // Reachable via WiFi
}

Calling SCNetworkReachabilityFlags on the main thread invokes a DNS lookup with a 30 second timeout. This is bad. Don’t make blocking, synchronous calls to SCNetworkReachabilityFlags.