Synchronous vs asynchronous networking programming

When I first started learning how to write code, everything I wrote was done sequentially with some goto loops; it waited for input, did something and then waited for more input. When I started writing network code on Mac OS, I had to fumble through Universal Procedure Pointers (UPP) in order to wait for connections and not block the user interface. Now that we’re into the golden age of Mac OS X and iOS, those days are behind us. Most network programming is done with NSURLConnection either the synchronous or asynchronous calls.

The synchronous call

+ (NSData *)sendSynchronousRequest:(NSURLRequest *)request
	returningResponse:(NSURLResponse **)response
	error:(NSError **)error

is quite easy to use as it simply returns an NSData object. Anyone that has done iOS programming knows, you absolutely cannot use this call on the main thread as it blocks and won’t return until it times out, errors out, or returns data. The iOS watchdog timer will kill an unresponsive application as outlined in an Apple technote.

So what many developers do is either wrap this call in an NSOperation or simply perform it on a separate thread. This allows the user interface to be responsive and won’t get the application killed by the watchdog timer.

However, this is probably not the best way to handle network calls and I’m kind of disappointed that Apple has even provided the method. There are a number of things that the synchronous call can’t do (even in a background thread):

  • Requests can’t be cancelled. Once you issue the call, it only returns when it times out, when it gets an error, or gets the data back. There are many cases where you want to cancel a request; for instance, if you’re loading a bunch of images and a use exits a screen, you should cancel the outstanding requests.
  • Authentication can only be specified at the start of the call. Using NSURLProtectionSpace, the authentication can be specified as part of the request. If you want a user to enter a username/password based on an HTTP 401 error, you can’t do this with a synchronous call.
  • Responses can only be handled at the end. For instance, redirect (page moved requests) can’t be acted upon until all the data is downloaded whereas with an asynchronous call, you get the response once the header is downloaded. A former Apple engineer, Jens Alfke, wrote that basically the synchronous call treats many response as errors instead of recoverable conditions.

The first point is my biggest problem with the synchronous call and people might say that if you never want to cancel the call, who cares? That seems a bit short sighted to me.

Using the code that Dave Dribin wrote on concurrent NSOperations you can easily construct a nice asynchronous networking class and queuing mechanism. I’ve done this twice and there is no reason that I can think of to still use synchronous networking calls on iOS.

I’m sure that some people will argue with my logic and that’s fine. I’ve been writing networking code for my entire career and while I’m not going to claim to be an expert on it, I’ve seen good and ugly (mostly written by me). The synchronous calls look quick and dirty while the asynchronous calls look like a lot of work. I agree with a friend of mine when he said in a StackOverflow discussion that asynchronous calls were the “The Right Way”.

In fact, asynchronous networking calls really aren’t a lot of work. I was scared of asynchronous networking calls until I started writing Objective-C code; you just have to structure your code with delegates and handle the callbacks. I believe you should do this wrapped in an NSOperation to make sure that you only have a few networking calls outstanding at a time (you really only have so much bandwidth so trying to flood the channel with calls isn’t going to be all that effective). In addition, this will help properly display the network activity indicator on iOS.

Can anyone think of a reason besides “it’s easier” to use the synchronous version of NSURLConnection vs the asynchronous call?

2 Replies to “Synchronous vs asynchronous networking programming”

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.