Home > 2010 Fall DPS913 > Consume JSON from a RESTful web service in iOS

Consume JSON from a RESTful web service in iOS

November 4, 2010 Leave a comment Go to comments

In this post, you will learn to consume JSON from a RESTful web service in iOS. In a later post, you will learn to code the full range of RESTful web service operations.

One of the characteristics of a good iOS app is its supporting web services. A device that runs iOS is also typically a mobile device which relies on network communication, so iOS apps that use web services are and should be very common. We’ll introduce you to the consumption of web service data today, and build a foundation for more complex operations in the future.

.

Web services definitions

Web services are applications with two characteristics:

  1. A web service publishes, and is defined by, an application programming interface (API) for the data and functionality it makes available to external callers
  2. A web service is accessed over a network, by using the hypertext transfer protocol (HTTP)

.

Modern systems today are often built upon a web services foundation. There are two web app API styles in wide use today: SOAP XML Web Services, and RESTful Web Services. In this course, we will work with RESTful web services.

A RESTful web service is resource-centric. Resources (data) are exposed as URIs. The operations that can be performed on the URIs are defined by HTTP, and typically include GET, POST, PUT, and DELETE.

There are two web services data payload formats in wide use today: XML and JSON. Both are text-based, language-independent, data interchange formats.

  • Web Services use XML, specifically XML messages that conform to (the) SOAP (protocol).
  • REST typically uses either XML or JSON messages.

In this course, we will work with the JSON data payload format.

The JSON format can express the full range of results from a web service, including:

  • A scalar (i.e. one value) result
  • A single object (or data structure)
  • A collection of objects (or data structures)

.

Introduction to JSON

JSON is a text-based language-independent data interchange format.

It is described in RFC 4627.

JSON defines a small set of formatting rules for the portable (i.e. serializable) representation of structured data. JSON can represent the following types; the first four are primitive types, and the last two are structured types:

  • string
  • number
  • boolean
  • null
  • object
  • array

.

Locating help documentation

Your professor suggests that you study the following JSON documents before continuing:

Seven JavaScript Things I Wish I Knew Much Earlier In My Career blog post, specifically these sections:

  • Shortcut Notations
  • JSON As A Data Format

JSON.org home page

Wikipedia article on JSON

.

Recognizing JSON

As you saw in the documentation links above, JSON is uncomplicated. A JSON container will be either an object, or an array. Inside the container, you can place other containers, or primitive types.

An object will be wrapped in { } curly braces.

An array will be wrapped in [ ] brackets.

Many web services that deliver JSON will wrap the requested data in an object wrapper, to reduce security vulnerabilities. In these situations, you will have to unwrap the data, before you assign it to an object in your app.

.

Examples of publicly-available web service APIs

In this course, you will not learn how to create and maintain web services. (Seneca has another course for learning web services programming.) Instead, we will use a few publicly-available web service APIs, and learn how to work with them from iOS apps.

We will work with the Twitter API. (If you need some orientation to Twitter, read their “about Twitter” information, or the Wikipedia article.)

The Twitter API offers text-oriented resources, which can be requested anonymously, or by presenting your authentication credentials.

We will also work with the Flickr API. (If you need some orientation to Flickr, read their “about Flickr” information, or the Wikipedia article.)

The Flickr API offers image-oriented resources, which typically require an “API key” as part of the request.

Other APIs, which we will likely not cover in this course, include the following:

.

Getting started toolset

To get started, we will use a browser to query the APIs. This will provide us with a simple way to see results.

The results will be returned as JSON data (which is a string). However, the default configuration of browsers does not display the results. Instead, the browser will present a dialog, asking us whether we want to save or open the resource.

There is a Firefox add-on named JSONview, which will solve this problem. It enables Firefox to retrieve the JSON data, and JSONview will display the data in a tree-structured syntax-coloured format. Nice.

.

Querying the Twitter and Flickr APIs

We will start with the Twitter API. It can be used anonymously, and the results do not contain images.

The API documentation for the GET search query is at this link. It instructs us to use the following URI (assuming that we want to see the most recent tweets of Scott Guthrie):

http://search.twitter.com/search.json?q=@scottgu

The returned results are JSON. Without the JSONview add-on, you are prompted to save or open. If you save, and then open it (using TextEdit for example), you will see the unformatted JSON data, as shown in the following image:

Alternatively, if you use the JSONview add-on, it will appear in Firefox, as shown in the following image:

The dashes ( – ) are NOT part of the JSON. They are click targets, and allow you to toggle the show/hide status of the object.

Most RESTful web services wrap the JSON results in a top-level object. As you can see from the above images, the top-level object name is “results”. Its value is an array, which is the data that we’re interested in.

If we have more time, we will look at the Flickr API later. You are welcome to look at it on your own time.

.

JSON and iOS

iOS (version 4.x at the time of writing this) does not have much built-in support for handling JSON data. However, some developers “out there” have created libraries that help. One oft-cited library is the json-framework, a project that is hosted on Google Code. We will use json-framework to convert JSON to-and-from Cocoa objects.

There are many tutorials which cover the process of downloading and using json-framework. Use a search engine to locate them, and skim through them to get familiar with the process. In summary, you typically have to copy the folder with the json-framework source code (the “Classes” folder in the JSON v2.3.1 (iPhone) download, obtained on November 3, 2010) into your project. A recommended location in your Groups & Files organizer is the “Classes” folder. (If you want to rename the json-framework folder to “json-framework” or something similar, go ahead.)

When you wish to use json-framework in one of your classes, then import the following header:

#import “JSON.h”

The json-framework has a method that will convert web service JSON into an array or a dictionary:

  • A JSON object will become an NSDictionary
  • A JSON array will become an NSArray

You must learn and discover the format of the JSON data from a web service. Typically, you will not attempt to dynamically determine this in your code. You really must know something about the “shape” of the data before you attempt to process and use it.

.

Introduction to network operations in iOS

For most network operations, the typical use case is that the request and response is performed in an asynchronous manner. This is usually a good thing, because the network operation will not block the execution of your app’s other code.

There is a best practice pattern for coding iOS apps that perform asynchronous network operations. The pattern is summarized by the following steps:

  1. Configure an NSMutableData property to receive the response from the server
  2. Create an NSURLRequest object, which typically requires a string URI
  3. Create an NSURLConnection object, which gets initialized with the request object

.

When the connection object is created, it immediately sends the request to the server. The connection object is designed to rely on delegate methods, which process the response from the server. Therefore, you must implement some delegate methods. Which ones? Read/skim the documentation for the NSURLConnection Class Reference for full details, but we suggest at least the following:

  • connection:didReceiveResponse:
  • connection:didReceiveData:
  • connectionDidFinishLoading:
  • connection:didFailWithError:

.

In the following section, you will learn the coding pattern for a network operation. A request will be sent to a Twitter web service (using the URI from earlier in this post). The response will be returned as JSON. Then, a table view will be configured with the data. A table view row can be tapped, and details about the selected tweet will be displayed with a standard view controller.

.

Coding pattern

The “Read Tweets” example app implements the principles shown above, and the coding pattern discussed below.

First, configure the view controller with an NSMutableData property. The raw response is returned as NSData. It may require multiple responses to fully deliver the requested data, so we need a mutable NSData object.

Then, when you’re ready perform the request, initialize the property:

dataToBeLoaded = [[NSMutableData alloc] init];

Now, create an NSURLRequest object which requires an NSURL:

NSURL *url = [NSURL URLWithString:@"http://search.twitter.com/search.json?q=@scottgu"];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];

Next, create an NSURLConnection object, using the NSURLRequest:

NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];

Note that the initialization required you to name a delegate. The current view controller (i.e. “self”) will hold/implement the delegate methods.

Now, you’re ready to implement the delegate methods.

You don’t have to do much in connection:didReceiveResponse:. You may want to log a message to the debug console.

For connection:didReceiveData:, you will append data to the NSMutableData property. Depending upon the size of the incoming response, the Cocoa runtime may call this method multiple times.

After the last response package has been received, the server will close the connection, and the Cocoa runtime will call the connectionDidFinishLoading: method. In this method, you will convert the NSMutableData property into a string, and then use a method in the json-framework to convert it into a dictionary.

We know – from inspection and observation – that the response data is in an object wrapper. The token “results” is the name/key for the object. The object itself is an array – which is the data we really want.

Therefore, we 1) assign the response data to a new NSDictionary object, and then assign its objectForKey:@”results” to an NSArray property (which is a data-bearing property on the view controller).

The array holds the data that is needed for the table view. The only wrinkle at this point in time is that the table view has already been rendered; that happened when the view nib was unarchived. Therefore, now that we have the response data in the array, we have to reload the table view.

Check the “Read Tweets” example app for a full implementation. That code has been generously commented, so study the code carefully.

.

Destinations for web service results

There are a number of possibilities for handling the response data. You can choose to use it and discard it, or persist the data. Here are some choices:

  • Use the data in the current view controller, and then discard the data
  • Save the data in a plist or archive
  • Persist the data using Core Data
  • Send the data to another/a different web service endpoint

.

The plan is to cover some of these destinations in more detail, with additional posts and examples.

.

Summary

In this post, you were introduced to read-only network operations – receiving JSON-formatted data from a web service. You learned patterns for performing network operations, and how to include a third-party chunk of code (i.e. the json-framework) in your app. In later posts and example apps, you will learn the complete range of network operations, including sending/updating a web service with changes you perform on your iOS device.

.


About these ads
Categories: 2010 Fall DPS913
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 47 other followers

%d bloggers like this: