Online Book Reader

Home Category

iOS Recipes - Matt Drance [65]

By Root 225 0
downloadData property. You can also check the length of the downloadData’s bytes array if you want to display that information to the user as the download progresses.

Explore the SimpleDownloadViewController class implementation provided with the SimpleDownloads test project, and note how few lines of code are needed to handle the actual download: nearly all the work is limited to manipulation of the user interface. This abstraction of NSURLConnection allows us to keep our controller code clean and focused on its important, higher-level tasks. We can use it to acquire RSS feeds, get JSON responses from web services, and even download media.

Note that for large downloads, you’ll want to wire this up to an NSInputStream and write the data to disk as it comes down in order to avoid memory pressure. Downloading a 500MB video directly to an NSData object in memory, for example, will inevitably crash your app.

Recipe 33 Format a Simple HTTP POST

Problem

New web service APIs pop up every day. Sooner or later one of them will require an HTTP POST instead of a plain old GET. How do you format such a request? How do you make it easy for every project that needs it?

Solution

If you’ve used (or coded for) the Web, you’re no stranger to POST methods. When filling out a form on a web page with basic drop-downs and text fields, followed by some kind of “submit” action, that form probably produces a “form” or “URL encoded” POST. On the Web, however, the browser does the dirty work. What’s a Cocoa programmer to do?

The good news is we can do a POST with the same NSURLConnection API we’ve used for other more basic web requests (usually GET methods). Submitting a POST involves a few simple additions:

Setting the request method to POST

Identifying the type of POST we’re submitting

Adding form data to the request body

The connection itself is unchanged; it’s the supporting NSURLRequest that needs modification. To do this, we’ll write a subclass of NSMutableURLRequest, PRPFormEncodedPOSTRequest, which supports a dictionary of parameters to be used in the POST method. We subclass NSMutableURLRequest so we can add the form data to the HTTP body.

BasicHTTPPost/PRPFormEncodedPOSTRequest.h

@interface PRPFormEncodedPOSTRequest : NSMutableURLRequest {}

+ (id)requestWithURL:(NSURL *)url formParameters:(NSDictionary *)params;

- (id)initWithURL:(NSURL *)url formParameters:(NSDictionary *)params;

- (void)setFormParameters:(NSDictionary *)params;

@end

The first two steps outlined earlier are simple: set the HTTP method to POST, and set the content type to application/x-www-form-urlencoded. We can do this work at initialization time.

BasicHTTPPost/PRPFormEncodedPOSTRequest.m

- (id)initWithURL:(NSURL *)url formParameters:(NSDictionary *)params {

if ((self = [super initWithURL:url])) {

[self setHTTPMethod:@"POST"];

[self setValue:@"application/x-www-form-urlencoded"

forHTTPHeaderField:@"Content-Type"];

[self setFormParameters:params];

}

return self;

}

That ‑setFormParameters: method is the remaining piece of the puzzle. In the case of our ‑initWithURL:formParameters: method, the parameters are passed at creation time, but we could also set them after creating the object, so it’s broken out into a separate method.

Form parameters look a lot like a URL query string, but instead of being appended to the URL, they’re placed in the HTTP body. So, if we are submitting a form that includes your name and age, the composed body string might look like this:

name=Lucas+Drance&age=1.5

Each parameter’s name and value are connected with an equal sign (=), and the pairs are connected with an ampersand (&). In this recipe, we use %20 to escape spaces, rather than the plus (+) characters specified by RFC 2616. In practice, many servers accept either, but unfortunately many popular web services don’t support the plus sign. Always test your project with whitespace content to make sure the server you’re talking to is behaving as expected.

So, given a set of name-value pairs, our Cocoa code needs to tie them together,

Return Main Page Previous Page Next Page

®Online Book Reader