8
\$\begingroup\$

I have successfully coded a network request to fetch JSON data from our server. The remote function is written in ColdFusion. However, the code is quite lengthy and involved. I also noticed in the API there are other seemingly very similar ways one can go about making network requests, such as NSURLSession. (I know NSURLConnection will be deprecated in the future, replaced by NSURLSession.) I would like to know what is the best way to make a network request - using modern code that is not going to be deprecated in the near future. Is NSURLSession the best way to go?

Here are my requirements:

  • Fetch JSON data from a function in a .cfc file on the server
  • Must be secure
  • Must be able to perform error checking
  • Only need to support iOS 7+
  • Preferably more concise code

Here is my current and lengthy code, using several variables, NSMutableURLRequest, and NSURLConnection:

dispatch_queue_t queue = dispatch_queue_create("Q", NULL);
dispatch_async(queue, ^{
    NSInteger success = 1;

    NSURL *url = [NSURL URLWithString:MYURL];
    NSData *postData = [[[NSString alloc] initWithFormat:@"method=methodName&username=%@&password=%@", usernameVar, passwordVar] dataUsingEncoding:NSUTF8StringEncoding];
    NSString *postLength = [NSString stringWithFormat:@"%lu", (unsigned long)[postData length]];

    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
    [request setURL:url];
    [request setHTTPMethod:@"POST"];
    [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
    [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
    [request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
    [request setHTTPBody:postData];

    NSError *requestError = [[NSError alloc] init];
    NSHTTPURLResponse *response = nil;
    NSData *urlData = [NSURLConnection sendSynchronousRequest:request
                                            returningResponse:&response
                                                        error:&requestError];

    //if communication was successful
    if ([response statusCode] >= 200 && [response statusCode] < 300) {
        NSError *serializeError = nil;
        NSDictionary *jsonData = [NSJSONSerialization
                                  JSONObjectWithData:urlData
                                  options:NSJSONReadingMutableContainers
                                  error:&serializeError];
        success = [jsonData[@"ERROR"] integerValue];

        if (success == 0) {
            //success! do stuff with the jsonData dictionary here
        }
        else {
            //handle ERROR from server
        }
    }
    else {
        //handle error for unsuccessful communication with server
    }
});

Could you help me clean this up to be implemented the most preferred way for modern apps of today?

\$\endgroup\$
7
\$\begingroup\$

NSURLSession was designed from the ground up to be as similar to NSURLConnection as possible, so that those accustomed to using the latter will have no problem transitioning to the former. Meanwhile, NSURLSession has a lot of major advantages over NSURLConnection.

First of all, we can get rid of all the code for dispatching on a background thread. NSURLSession works on background threads automatically unless we specify otherwise.

We still have to create our NSURLRequest. I don't know any way around this.

But once we've got our request set up, and remember, all of this is outside the GCD block, we just do this:

NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];

[[session dataTaskWithRequest:request 
            completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {

    // do stuff

}] resume];

As you can see, it's quite similar to NSURLConnection. We replace // do stuff with the stuff we want to do when the request is complete (completion handler). We have our data, our response, and our error all in this block.

A lot of the new power from NSURLSession comes from the NSURLSessionConfiguration object. Using NSURLSessionConfiguration, we can easily set up downloads/uploads to happen in the background (when our app is not open). We can specify to only run on Wi-Fi and not use cellular data as setting a BOOL. We can set a BOOL to tell the OS to only try doing our background uploads/downloads when the device is on Wi-Fi and plugged into a power source.

NSURLSessionConfiguration also has an HTTPAdditionalHeaders property, which is an NSDictionary object containing additional headers that should be sent with requests using this configuration.

There's a lot more information about NSURLSessionConfiguration here.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.