This is my 2nd blog post on the topic of iPhone development and I am happy to share with you yet an another open source project of mine: IZURLConnection
Basically it mimics NSURLConnection, has the same delegate callbacks, and heck it uses NSURLConnection as it's back-end, BUT it has 2 nifty features:
1. Robust (uses Reachability v2.0)
Network connections on a mobile device are terrible. Or worse. Connection is spotty and if you happen to issue an NSURLConnection when the device is/goes dark (e.g. enters into a tunnel or a stargate wormhole) then you'll end up with a delegate call with an error like (all NSURLErrorDomain domain error codes): NSURLErrorNotConnectedToInternet, NSURLErrorCannotFindHost, NSURLErrorCannotConnectToHost, NSURLErrorTimedOut
In my real life experiments NSURLErrorNotConnectedToInternet is an error that is permanent and lasts longer while the others are transient. They are usually present when there's a glitch e.g. switching between network connection types (3G, EDGE, WiFi). IZURLConnection does not notify the delegate with NSURLErrorNotConnectedToInternet. It uses the Reachability class provided by Apple and waits until the host provided in the request will be reachable again and automatically retries. In the other (transient) error cases it retries by default 2 times before notifying the delegate of the error.
This takes a little bit of error handling off of your shoulders. But wait, there is more. Continue reading.
2. Simple and easy way to notify the user of network activity
When it starts or finishes loading it posts a NSNotification instance. If there are network connections out there then you are safe to assume that your network indicator on the device should be spinning and you should switch it on. Take a look at the following code snippet in the appdelegate:
- (void)applicationDidFinishLaunching:(UIApplication *)application {
networkConnections = 0;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(IZURLConnectionDidStart:)
name:IZURLConnectionConnectionDidStartNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(IZURLConnectionDidFinish:)
name:IZURLConnectionConnectionDidFinishNotification
object:nil];
// Override point for customization after app launch
[window addSubview:viewController.view];
[window makeKeyAndVisible];
}
- (void)updateNetworkActivityIndicator
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = (networkConnections != 0);
}
- (void)IZURLConnectionDidStart:(NSNotification *)notification
{
// Only increment networkConnections if the request is a network protocol
// Assuming that NSURLConnection handles the following protocols: ftp, http, https, file
// Assuming that file is the only protocol that is not a network protocol
IZURLConnection *connection = (IZURLConnection *)[notification object];
if ([connection.request.URL.scheme isEqualToString:@"file"] == NO)
{
networkConnections++;
[self updateNetworkActivityIndicator];
}
}
- (void)IZURLConnectionDidFinish:(NSNotification *)notification
{
// Only decrement networkConnections if the request is a network protocol
// Assuming that NSURLConnection handles the following protocols: ftp, http, https, file
// Assuming that file is the only protocol that is not a network protocol
IZURLConnection *connection = (IZURLConnection *)[notification object];
if ([connection.request.URL.scheme isEqualToString:@"file"] == NO)
{
networkConnections--;
[self updateNetworkActivityIndicator];
}
}3. All your current NSURLConnection code will work if you refactor to IZURLConnection
Well, this isn't entirely true. IZURLConnection currently doesn't implement NSURLConnection's Runloop Scheduling methods:
- (void)scheduleInRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode - (void)unscheduleFromRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode
If you wish to extend it though, go ahead. At the current state it gets the job done. I've never used runloop scheduling with NSURLConnection anyway.
Important note: Be prepared to receive multiple delegate messages as IZURLConnection may retry multiple times.
That's it. Take it away.

0 comments:
Post a Comment