简体   繁体   中英

iOS NSJSONSerialization nesting NSDictionary as a key when serializing for POST request

I'm attempting to post some data to a RoR server I'm running but am having trouble with how the NSDictionary I'm trying to send is formatted after serialization.

Here is my Objective C code:

- (void)registerUser:(NSString *)provider uid:(NSString *)uid
         inviteCode:(NSString *)inviteCode userInfo:(NSDictionary *)userInfo
{
    NSLog(@"Attempting to register user");

    // Construct the data to post
    NSDictionary *post = @{
        @"provider": provider,
        @"uid": uid,
        @"invite_code": inviteCode,
        @"user_info": userInfo
    };
    // TODO need to format better so it works with rails
    NSData *data = [NSJSONSerialization dataWithJSONObject:post options:0 error:nil];

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:_registerUserURL]];
    [request setHTTPMethod:@"POST"];

    NSURLSession *session = [NSURLSession sessionWithConfiguration:_defaultConfig];
    NSURLSessionUploadTask *task = [session uploadTaskWithRequest: request
            fromData: data completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
        NSLog(@"%@", json);
    }];

    [task resume];
}

I expected this to post data to my RoR server in the following format:

{\\"user_info\\":{\\"name\\":\\"Matt Fornaciari\\",\\"email\\":\\"mattforni@gmail.com\\",\\"city\\":\\"San Francisco, California\\"},\\"provider\\":\\"facebook\\",\\"uid\\":\\"10202835053250675\\",\\"invite_code\\":\\"a\\"}

However the serialization process seems to be nesting my dictionary:

2014-12-09T04:20:14.366921+00:00 app[web.1]: Started POST "/users/register" for 67.160.200.20 at 2014-12-09 04:20:14 +0000
2014-12-09T04:20:14.439711+00:00 app[web.1]: Completed 400 Bad Request in 22ms (Views: 0.2ms | ActiveRecord: 0.0ms)
2014-12-09T04:20:14.417370+00:00 app[web.1]: Processing by UsersController#register as */*
2014-12-09T04:20:14.417422+00:00 app[web.1]:   Parameters: {"{\"user_info\":{\"name\":\"Matt Fornaciari\",\"email\":\"mattforni@gmail.com\",\"city\":\"San Francisco, California\"},\"provider\":\"facebook\",\"uid\":\"10202835053250675\",\"invite_code\":\"a\"}"=>nil}

So all of my data arrives, but it's nested within another Map as a key which points to a nil value and makes all of the data unreadable to Ruby. Anyone experienced this and have any advice?

So it looks like NSJSONSerialization doesn't appear to play nicely with sending JSON to a rails application. I was able to work around the problem by manually creating the NSData object from a string. Below is the code I used to encode my parameters.

// Construct the data to post
NSString *post = [NSString stringWithFormat:
    @"provider=%@&uid=%@&invite_code=%@&user_info[name]=%@&user_info[email]=%@&user_info[city]=%@",
    provider, uid, inviteCode, userInfo[@"name"], userInfo[@"email"], userInfo[@"city"]
];
NSData *data = [post dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];

// Create and send the request
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:_registerUserURL]];
[request setHTTPMethod:@"POST"];
NSURLSession *session = [NSURLSession sessionWithConfiguration:_defaultConfig];
NSURLSessionUploadTask *task = [session uploadTaskWithRequest: request
        fromData: data completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
    NSLog(@"%@", json);
}];

I was having the same problem, and it's a surprisingly straightforward fix. You just need to set the content type to "application/json" in the request, or else your HTTP request is is not interpreted properly and results in this strange error.

To fix this, you can add the following line after your call to setHTTPMethod in your original post:

[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM