Using blocks and Grand Central Dispatch for asynchronous web calls

Today at work, we were talking about building a REST framework and someone described how they made NSURLConnection behave synchronously. That seemed strange to me. Then, he told me that using Grand Central Dispatch made it easier to deal with threads than dealing with the delegate stuff in NSURLConnection.

I’ve been hearing about how great Grand Central Dispatch is for awhile so when I heard about a practical application of it, I decided to learn about it myself. A little bit of googling led me to a post at Cocoa Samurai. It seems to be a pretty good overview of GCD and blocks.

Based on some stuff I learned from there, I built a little demo app that uses GCD and blocks to make synchronous web calls asynchronous.

The app is a url shortener, if you want to try it out, first you’ll have to get an API key from bit.ly. (It’s super easy, just go to http://bit.ly/a/your_api_key/ and log in or sign up). Alright, lets get started.

First I made a simple UI with a button and a couple of text fields. One is for the URL you’re going to shorten and the other is for the short URL. Then I hooked up the button to an IBAction called shortenURL:

shortenURL: gets the URL from the first text field and passes it into some blocks that call a synchronous method for shortening the URL and then when that is done, another block updates the UI with the shortened URL. Here’s the function:

-(IBAction)shortenURL:(id)sender
{
   [spinner startAnimation:nil];

   dispatch_queue_t queue = dispatch_queue_create("com.Blocks.task",NULL);
   dispatch_queue_t main = dispatch_get_main_queue();

   dispatch_async(queue,^{
      NSString* shortURL = [self shortenSynchronous:[urlField stringValue]];

      dispatch_async(main,^{
         [self updateUIWithShortURL:shortURL];
      });
   });
}

To explain the dispatch_queue_ts you’ll need to understand a little bit better how GCD works. When you get a new thread from GCD it grabs it from a pool of available threads. When you’re done with the thread, GCD takes it back so it can be used again. So when you create a thread, you have a little bit of control over where it comes from. This is what the queues are. You create different queues so you can have a little bit of control over what queues your thread dispatches from. At least that is my understanding of this stuff. I could be way wrong.

dispatch_queue_create(“com.Blocks.task”, NULL) creates a private queue that is just for my app. dispatch_get_main_queue() gets the main thread for your application.

Next up is dispatching the threads onto the different queues. The first dispatch_async() takes a block that calls the URL shortening function. Then, it dispatches a new block on the main UI thread to update the UI with the result of the url shortening function. It uses what Apple calls recursive decomposition to call it in the right order. I don’t fully understand how it works yet but the Cocoa Samurai post I talked about earlier goes into more detail.

Other than the UI updating code and the URL shortening code (which is only 3 lines) that is all I needed to do. With an NSURLConnection I’m stuck implementing delegate methods and appending data as it arrives and some other confusing things. This is much cleaner and shorter. The only problem with it is that I don’t fully understand how it works… yet.

You can download the demo and play with it too. Feel free to use and modify the code.

This entry was posted in Uncategorized and tagged , , , , , . Bookmark the permalink.

One Response to Using blocks and Grand Central Dispatch for asynchronous web calls

  1. bet365 says:

    how are you!This was a really marvelous website!
    I come from roma, I was fortunate to search your website in google
    Also I obtain much in your website really thanks very much i will come every day

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>