Introducing JBContainedURLConnection: A simplified, Blocks-based Wrapper Around NSURLConnection. If you build a project of any moderate size on iOS or the Mac, you'll almost certainly need to use
NSURLConnection at some point to load a resource asynchronously from the web (typically from a web service) (and you'll never do this with a method like
-loadDataFromURL:, because that blocks the main UI queue).
You'll follow the same basic pattern every time: build a string of the resource you're trying to grab, build an
NSURL, then an
NSHTTPRequest, then finally start an
NSURLConnection, setting yourself as the delegate, and have it fire off. Then you implement the same basic delegate callbacks for the class. Crap, you forgot to have an
NSMutableData to hold the bytes as they're streaming in to your callback objects, better add that too. Then, when it's done, you'll need to do something with this data, and clean up.
You've probably done this a dozen times, shoving these methods in controller classes where they don't entirely belong. The code is the same except for your error handling and your completion data handling, but you retype it (or worse: copy and paste it) again and again. No more.
JBContainedURLConnection as a class to wrap up all this work for you, simplifying the API to only the mere essentials—which are exactly what you'll need 99% of the time—along with some extra goodies to make your code even simpler.
There are two main ways to use this class: you can either use it with its own simplified delegate protocol, or use it with a Block object completion handler. You chose at initialization, and all the rest of the work is done for you. All you need to do is wait for completion (or error).
The delegate protocol is simple: you are required to implement exactly two methods, one for failure and one for success. Both callbacks pass to you the address of the resource you were trying to load, and the
userInfo context dictionary passed in at initialization. If the connection failed, you'll also get an error pointer. If the connection completed successfully, you'll instead get an
NSData pointer containing the resource you loaded. It's terrifically simple.
JBContainedURLConnectionCompletionHandler (Blocks based)
The simplified delegate protocol is nice, but it's still a lot of overhead in your code, as you've got to conform to the protocol, then make sure you've got both methods implemented in your implementation file. The Blocks-based route is much simpler.
All you do is call the initializer with a completion handler option, and implement the Block object right in line. This Block object is invoked on success or failure: if the
error pointer is non-nil, this means there was an error, and you should act accordingly; otherwise the connection loaded your resource successfully and you can use the data. This route essentially combines the two delegate callbacks into one Block object execution, drastically simplifying your code.
Requirements and Future development
The class is pretty lightweight and simple, but it does have some requirements. It's iOS 5+ for the build environment as it uses Automatic Reference Counting for memory management. Lucky for you, ARC is backwards compatible down to iOS 4, so with little modification, this should run just fine on iOS 4 as well.
The class is very simple and suits 99% of my needs, replacing swaths of boilerplate code, simplifying my callbacks, and allowing me to perform asynchronous requests as elegantly as using a synchronous approach. With none of the downsides and all of the elegance. There may be some reasons to extend this class on your own, especially if you need to handle authentication, but it's still an excellent drop-in as is. If you do decide to extend the class, please fork it on Github and send me a pull request.