Advertisement
iOS SDK

iOS Quick Tip: Interacting with Web Services

by

At some point in your iOS development career, you will have the need to interact with a web service from within your app. You may need to access remote data, parse a social network feed, or even download some assets into your application. This quick tip will teach you to do so without using third party libraries!

There are some incredible third party libraries out there to help facilitate web service interactions, including ASIHTTPRequest, AFNetworking, and RESTKit. While these libraries are incredibly useful, sometimes they are a little bit overkill. They add quite a bit of unneeded code bloat to an app via extra variables in memory, and also modify your workflow to adjust to the workflow of each library.


Simplifying

I used to use some of these libraries (and more!) as a crutch. I felt using them sped up development time and reduced complexity. While this is true in many cases, these are not "one size fits all solutions". Additionally, you are adding complexity unless you fully understand everything under the hood of these libraries.

Today, I am going to show you a much simpler approach to interfacing with web services and downloading data from the web. I have recently used this approach in my new iOS MUD client Pocket MUD Pro to fetch remote audio, settings, and data. This approach involves using the "built-in" technologies for downloading, parsing and using remote JSON as well as assets such as images and sounds.


Fetching Remote Data

In iOS versions prior to 4, it was quite a pain to fetch data asynchronously. You usually had to create a full blown class dedicated to making requests and then another to parse and use the responses. With Grand Central Dispatch (GCD), you can now do this inline and keep your code short and clean. Here you will see some code that fetches a remote JSON document from the web:

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    dispatch_async(queue, ^{
        NSError *error = nil;
        NSURL *url = [NSURL URLWithString:@"http://brandontreb.com/apps/pocket-mud-pro/promo.json"];
        NSString *json = [NSString stringWithContentsOfURL:url
                                                  encoding:NSASCIIStringEncoding
                                                     error:&error];
        NSLog(@"\nJSON: %@ \n Error: %@", json, error);
    });

This code starts by fetching one of Apple's three dispatch queues that you are able to use for asynchronous execution and runs a block on the queue with default priority. You could just as easily have created your own queue. Either way, this allows our code to run in a separate thread from the main thread through the power of Grand Central Dispatch (GCD).

We then build the URL and stick it into the stringWithContentsOfURL:encoding:error: method of NSString to fetch the JSON data. Finally, the return string gets printed out along with the error (if there is one).

This approach is very rapid, but doesn't give you a ton of control. Although you know what an error might be, it doesn't allow you to specify a timeout in the event of an error. The default timeout is somewhere around 30 seconds. If you want some additional control over timeout and such, replace the string method with an NSURLConnection.


Parsing JSON

As of iOS 5, Apple has a built-in JSON parser which allows you to take a string containing JSON and convert it into an NSDictionary or an NSArray. In order to parse and use the JSON returned in the code above, add these lines before the end of the block:

if(!error) {
    NSData *jsonData = [json dataUsingEncoding:NSASCIIStringEncoding];
    NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:jsonData 
                                                                options:kNilOptions
                                                                  error:&error];
    NSLog(@"JSON: %@", jsonDict);
}

The NSJSONSerialization class will parse and convert a JSON string into an NSDictionary or NSArray depending on the format of your JSON. This makes your life much, much easier. Now you are able to use the values from the JSON string like this:

NSString *promo_url = [jsonDict objectForKey:@"promo_url"];

And there you have it! A very basic way to consume web services using ONLY native SDK classes. Now, on to something a little more interesting...images!


Fetching Remote Images

We can use the method described above to fetch any sort of remote media. For this example, I will show you how to download an image from the popular blog XKCD.

    dispatch_queue_t img_queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(img_queue, ^{
        
        NSURL *url = [NSURL URLWithString:@"http://imgs.xkcd.com/comics/formal_logic.png"];
        NSError *error = nil;        
        NSData *image = [NSData dataWithContentsOfURL:url options:0 error:&error];
        
        if(!error && image && [image length] > 0) {
            NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
            NSString *path = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"image.png"];
            
            [image writeToFile:path options:0 error:&error];              
        }

Again, we start by getting a queue to run asynchronously on. Next, we fetch the image data using the dataWithContentsOfURL:options:error: method of NSData. Once we verify that we have returned some data, we grab a reference to the caches directory on disk and save the image.

And it's that simple! You can also use the fetched image right away by doing this:

UIImage *img = [UIImage imageWithData:image];

Conclusion

I hope this article has helped you to remove your crutch on third party libraries in order to interact with the web. You should now have the knowledge to create a full blown web application. If you have any questions or comments, please leave them here or write me on Twitter.

Happy Coding!

Related Posts
  • Code
    iOS SDK
    Securing and Encrypting Data on iOSPs8e2e preview image@2x
    Whether you're creating a mobile application or a web service, keeping sensitive data secure is important and security has become an essential aspect of every software product. In this tutorial, I will show you how to safely store user credentials using the application's keychain and we'll take a look at encrypting and decrypting user data using a third party library.Read More…
  • Code
    iOS SDK
    Working with NSURLSession: Part 4E548b preview image@2x
    In the previous tutorial, we started creating a simple podcast client to put what we've learned about NSURLSession into practice. So far, our podcast client can query the iTunes Search API, download a podcast feed, and display a list of episodes. In this tutorial, we zoom in on another interesting aspect of NSURLSession, out-of-process downloads. Let me show you how this works.Read More…
  • Code
    iOS SDK
    Working with NSURLSession: Part 3E548b preview image@2x
    In the previous tutorials, we explored the fundamentals of the NSURLSession API. There is one other feature of the NSURLSession API that we haven't look into yet, that is, out-of-process uploads and downloads. In the next two tutorials, I will show you how to create a very simple podcast client that enables background downloads.Read More…
  • Code
    iOS SDK
    Networking with NSURLSession: Part 2E548b preview image@2x
    In the previous tutorial, I introduced you to NSURLSession. I talked about the advantages it has over NSURLConnection and how to use NSURLSession for simple tasks, such as fetching data from a web service and downloading an image from the web. In this tutorial, we'll take a closer look at the configuration options of NSURLSession and how to cancel and resume a download task. We've got a lot of ground to cover so let's get started.Read More…
  • Code
    iOS SDK
    Networking with NSURLSession: Part 1E548b preview image@2x
    From a developer's perspective, one of the more significant changes in iOS 7, and OS X Mavericks for that matter, is the introduction of NSURLSession. Even though NSURLSession may seem daunting at first glance, it's important that you understand what it is, how it relates to NSURLConnection, and what the differences are. In this series, I will take you through the fundamentals of NSURLSession so you can take advantage of this new technology in your own applications.Read More…
  • Code
    iOS SDK
    iOS 7 SDK: Background Transfer ServiceIcon ios7 v3
    This tutorial will show you how to use the background transfer service, a Multitasking API provided by iOS 7. I'll teach you how to create an app that will download a file without the application in the foreground. Once the file fully downloads, a notification message will pop-up. Continue reading to create this service!Read More…