Slides: Understanding Objective-C Inside and Out from CodeMash 2014

I braved the polar vortex to come down to Sandusky, OH for the always-amazing CodeMash conference. I gave a talk about Objective-C’s underpinnings in C and the like. You can find the slides on SpeakerDeck, and the slides and code on the unofficial GitHub repository for the conference. Thanks for coming, everyone!

Slides: Understanding Objective-C Inside and Out from CocoaHeads Ann Arbor

Last night I gave the Understanding Objective-C Inside and Out talk at CocoaHeads Ann Arbor. You can find my slides on SpeakerDeck.

We had a really great turnout—CocoaHeads Ann Arbor is almost outgrowing its space! If you’re in the SE Michigan area (or even further—there are attendees from Kalamazoo and Grand Rapids) you should come to the next meeting and learn about Auto Layout.

CocoaConf Columbus 2012 Slides and Code

Yesterday I gave a talk on concurrency in OS X and iOS at CocoaConf Columbus. As promised, here are the slides and code:

Enjoy!

Asynchronous Synchronous Requests: Effortless Networking Code

Today I showed a couple of people at work a technique I use to do asynchronous URL loading in iOS, and the response on Twitter was great, so I’ve written it up for everybody. If you’re used to using ASIHTTPRequest or rolling your own NSURLConnection delegates, hopefully this method will be a breath of fresh air.

The Problem: When you want to load something from the Internet, you don’t want to block your UI—especially when iOS might just kill your app for doing so—but writing delegate code is a pain. You have to remember which delegate methods get called in what order, to set yourself as the delegate (can’t tell you how many times that’s tripped me up), and handling multiple simultaneous connections with one delegate is… tricky, at best.

The Solution: Use Grand Central Dispatch. Maybe I just love GCD too much and this is me seeing everything as a nail, but let’s look at the following code for loading a URL:

- (void)loadAwesomeURL
{
    NSString *awesomeURI = @"http://www.awesomeexample.com/?output=JSON";
    NSURL *awesomeURL = [NSURL URLWithString:awesomeURI];
    NSURLRequest *awesomeRequest = [NSURLRequest requestWithURL:awesomeURL];

    NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:awesomeRequest
                                                                     delegate:self];

    [theConnection start];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    [myMutableData appendData:data];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    [self processTheAwesomeness];
}

That sucks. Three methods, and I didn’t even do any error handling! There has to be a better way. NSURLConnection offers a synchronous method, but everybody knows you don’t use it… so let’s do exactly that. But since we want to make this asynchronous, we’ll use Grand Central Dispatch to wrap it in a dispatch_async() call:

- (void)loadAwesomeURL
{
    NSString *awesomeURI = @"http://www.awesomeexample.com/?output=JSON";
    NSURL *awesomeURL = [NSURL URLWithString:awesomeURI];
    NSURLRequest *awesomeRequest = [NSURLRequest requestWithURL:awesomeURL];

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);
    dispatch_async(queue, ^{
        NSURLResponse *response = nil;
        NSError *error = nil;

        NSData *receivedData = [NSURLConnection sendSynchronousRequest:awesomeRequest
                                                     returningResponse:&response
                                                                 error:&error];

        [self processTheAwesomeness];
    });
}

We can easily do error checking after the NSURLConnection call; simply check to see if receivedData is nil, cast response to an NSHTTPURLRequest and check its statusCode property, and if all else fails, check out error.

Note: I’ve received a fair amount of negative feedback on this article on Twitter, Reddit, and in the comments, and I feel like I ought to make a few points clear:

  • This is not the last networking solution you’ll ever need. Among other things, this does not support:
    1. Canceling the connection
    2. Running code when the connection is half-done
    3. Streaming data to a file for large downloads
  • This is a quick example. It’s mainly designed to illustrate dispatch_async() as a wrapper for synchronous APIs.
  • It isn’t good for multiple connections. You’ll want a custom dispatch queue for that.
  • It doesn’t run on the main thread. If you’re updating your UI, you’ll need to do that on the main thread.