M. Uli Kusterer emailed me to say I’d forgotten that some people still have non-broadband connections. I had supposed that NSURLConnection would simply return an immediate error if the internet link is down – it turns out that it may autoconnect if the user has a dialup connection, for instance.
The way around that is to use the network reachability APIs. Here’s one way to insert that into the example below:
#include <SystemConfiguration/SCNetworkReachability.h>
...
- (id)initWithURL:(NSURL*)theURL delegate:(id)theDelegate {
if ((self = [super init])) {
SCNetworkConnectionFlags flags = 0;
if (SCNetworkCheckReachabilityByName([[theURL host] UTF8String], &flags)) {
const SCNetworkConnectionFlags mask =
kSCNetworkFlagsReachable|
kSCNetworkFlagsConnectionRequired|
kSCNetworkFlagsConnectionAutomatic|
kSCNetworkFlagsInterventionRequired;
if ((flags&mask)==kSCNetworkFlagsReachable) {
delegate = theDelegate;
data = nil;
conn = [[NSURLConnection alloc]
initWithRequest:[NSURLRequest requestWithURL:theURL]
cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
timeoutInterval:60.0]
delegate:self];
return self;
}
}
[self autorelease];
self = nil;
}
return self;
}
This changes the alloc/init pair to return nil whenever the URL host is unreachable… you’ll have to test for that of course.
Update: the downside to the above approach is that the SCNetworkCheckReachabilityByName() function will block until it gets the information – which may take several seconds, perhaps more on some systems. The solution I’m actually using is more complex, installing a reachability transition callback, which sets a global flag that is tested before activating the NSURLConnection.
Leave a Comment