John McClelland
John McClelland

Reputation: 62

Translating cURL request to NSMutableURLRequest

I'm a new Objective-C developer and I'm interacting with an API in the cURL format. I'm used to making calls using URLs, so I pieced together a request from what I found on the internets. I'm still not able to pull the data in my app.

This is the original cURL request (with dummy keys of course):

curl -v -H "app_id:12345" -H "app_key:abcdefg" -X POST "http://data.host.com/object" -d '{"Page":0,"Take":10}'

This is my attempt:

//Request
    NSURLSession *session = [NSURLSession sharedSession];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://data.host.com/object"]];

    //Set method
    request.HTTPMethod = @"POST";

    //Set parameters
    NSDictionary *parameters = @{
                                 @"Page": @(0),
                                 @"Take": @(10)
                                 };

    NSMutableString *parameterString = [NSMutableString string];
    for (NSString *key in [parameters allKeys]) {
        if ([parameterString length]) {
            [parameterString appendString:@"&"];
        }
        [parameterString appendFormat:@"%@=%@", key, parameters[key]];
    }
    NSLog(@"PARAMETER STRING: %@",parameterString);

    //Set headers
    [request setValue:@"12345" forHTTPHeaderField:@"app_id"];
    [request setValue:@"abcdefg" forHTTPHeaderField:@"app_key"];
    [request setHTTPBody:[parameterString dataUsingEncoding:NSUTF8StringEncoding]];

    NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        if (!error) {
            if ([data length]) {
                NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
                NSLog(@"JSON RESPONSE: %@", jsonResponse);
            }
        } else {
            NSLog(@"%@", error);
        }
    }];
    [task resume];
    NSLog(@"TASK: %@", task);

I don't get an error, but the jsonResponse returns NULL. Anybody have an idea on what I'm missing? Thanks in advance!

Upvotes: 0

Views: 516

Answers (1)

Rudi Angela
Rudi Angela

Reputation: 1473

You would see the difference if you compared the HTTP message exchanges between the curl version and your obj-c version. AFAICS you're missing a header for content type where you specify the encoding of the body. When posting you need to pass information on how you are encoding the body. Here is some example code from one of my apps:

- (NSURLRequest *)createPostRequestWithURL:(NSURL *)url
                          parameters:(NSDictionary *)parameters {

    NSLog(@"startGetTaskForUrl: %@, params %@", url, parameters);
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    [request setHTTPMethod:@"POST"];
    [request addValue:@"application/x-www-form-urlencoded"
   forHTTPHeaderField:@"Content-Type"];
    NSString * httpParams = [self createHttpParameters:parameters];
    NSLog(@"HTTPClient: postRequestWithURL body: %@", httpParams);
    [request setHTTPBody:[httpParams dataUsingEncoding:NSUTF8StringEncoding]];
    return request;
}

- (NSString *)urlEncodedUTF8String: (NSString *) source {
    return (id)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(0, (CFStringRef)source, 0,
                                                       (CFStringRef)@";/?:@&=$+{}<>,", kCFStringEncodingUTF8));
}

- (NSString *) createHttpParameters: (NSDictionary *) parameters {
    NSMutableString *body = [NSMutableString string];
    for (NSString *key in parameters) {
        NSString *val = [parameters objectForKey:key];
        if ([body length])
            [body appendString:@"&"];
        [body appendFormat:@"%@=%@", [self urlEncodedUTF8String: [key description]],
         [self urlEncodedUTF8String: [val description]]];
    }
    return body;
}

Upvotes: 1

Related Questions