In my iOS project, I would like to display a message to the user to connect to the internet before certain network operations, so I wrote the following check using Apple's Reachability class:
Reachability *reach = [Reachability reachabilityWithHostName:@"google.com"];
if([reach currentReachabilityStatus] == NotReachable) {
// ...prompt user to establish an internet connection
} else {
// ...send an asynchronous request with a timeout
}
However, this had one very big problem--when the device was on a very lossy network (for example, when uplink packet loss is set to 100% on OS X Lion's Network Link Conditioner), [Reachability reachabilityWithHostName:@"google.com"]
would block the main thread for 30 seconds before determining a connection was not available. The following code, however, does not block:
if([[Reachability reachabilityForInternetConnection] currentReachabilityStatus] == NotReachable) {
// ...prompt user to establish an internet connection
} else {
// ...send an asynchronous request with a timeout
}
Looking at the implementation of Reachability shows that both of these methods use SystemConfiguration.framework
, but the first method uses SCNetworkReachabilityCreateWithName
while the second uses SCNetworkReachabilityCreateWithAddress
. Why does the first method block, while the second does not? Is the second method a good way to check for connectivity? Or is there a better way?