Sunday, June 22, 2014

HTTP Post with JSON on iOS

Ever since iOS5, the iOS supports the JSON parsing API. The NSJSONSerialization Class could convert JSON to Foundation objects, and convert Foundation objects to JSON. The Foundation objects supported in the API are NSDictionary, NSArray, NSString, NSNumber. (Checkout the Document for detail.)
So, making a HTTP Request on iOS, it requires a NSURLRequest(HTTP Request) configured appropriately, and the NSData to be sent to the server.

1st, Construct the NSData.

NSMutableDictionary *json = [[NSMutableDictionary alloc] init];
[json setValue:[NSString stringWithFormat:@"%d", 2] forKey:@"user_id"];
This piece of code would have a NSDictionary ready with Keys & Values.
NSError *e = nil;
if (![NSJSONSerialization isValidJSONObject:json]) {
    NSLog(@"Invalid JSON format Data");
    return nil;
}

This piece checks if our constructed data is valid to be a JSON object to be converted.
NSData *data = [NSJSONSerialization dataWithJSONObject:json options:0 error:&e];
Then, this NSData object data is the data we will need to send to the server.

2nd, Configure the NSURLRequest

    //1, Create NSURLSession.
    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:nil delegateQueue:nil];
    
    //2, Create NSURLRequest
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://localhost:4730/adddata"]];

    // 3, Configure the Method of HTTP Request.
    [request setHTTPMethod:@"POST"];
    // 3, Configure the Body(Data) of HTTP Request.    
    [request setHTTPBody:[self postData]];
    // 3, Configure the Header of HTTP Request.    
    [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    
    // 4, Create DataTask with Callback function(Block) in it. The block will be fired once the server returns any data to the request.
    NSURLSessionDataTask *sessionDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        if (error) {
            // Handle the error;
            NSLog(@"Error: %@", error.localizedDescription);
        }
        NSDictionary* json = [NSJSONSerialization
                              JSONObjectWithData:data
                              options:kNilOptions 
                              error:&error];
        NSLog(@"Error: %@", error.localizedDescription);
        NSLog(@"Response POST: %@", json);
        
        dispatch_async(dispatch_get_main_queue(), ^{
            self.display.text = [NSString stringWithFormat:@"%@\n%@", json, self.display.text];
        });
    }];

    // 5, Fire the DataTask
    [sessionDataTask resume];
Here, the code
1st, Create a NSURLSession, which will generate a URLTask based on the URLRequest created later.
2nd, Create a NSURLRequest. Since we need to configure the request, then we make it mutable here. The exact URL is the string url, to which is the Restful API of the server.
3rd, Configure the Request with Method, Body(Data) and HTTPHeader.
4th, Create a DataTask which accomplishes the actual request operation. It has a Callback(Block) in it, which will be fired once the request accomplished, data will be received if the server returns any data, like confirmation data, etc.
5th, Fire the DataTask.