iOS NSJSONSerialization 嵌套 NSDictionary 作为 POST 请求序列化时的键

Posted

技术标签:

【中文标题】iOS NSJSONSerialization 嵌套 NSDictionary 作为 POST 请求序列化时的键【英文标题】:iOS NSJSONSerialization nesting NSDictionary as a key when serializing for POST request 【发布时间】:2014-12-09 04:44:45 【问题描述】:

我正在尝试将一些数据发布到我正在运行的 RoR 服务器,但在我尝试发送的 NSDictionary 在序列化后如何格式化时遇到问题。

这是我的 Objective C 代码:

- (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];

我希望这会以以下格式将数据发布到我的 RoR 服务器:

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

但是序列化过程似乎嵌套了我的字典:

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

所以我的所有数据都到达了,但它作为 key 嵌套在另一个 Map 中,它指向一个 nil 值并使所有数据对 Ruby 不可读。有人遇到过这种情况并有什么建议吗?

【问题讨论】:

请稍等,我正在尝试您的代码,稍后会通知您... 你能给我你的网址吗,我需要调用它来尝试你的代码... cove.ne/users/register 确保包含“www”,否则您将获得重定向 我收到无效网址的错误... 【参考方案1】:

所以看起来 NSJSONSerialization 在将 JSON 发送到 rails 应用程序时似乎不能很好地发挥作用。我可以通过从字符串手动创建NSData 对象来解决该问题。下面是我用来编码参数的代码。

// 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);
];

【讨论】:

【参考方案2】:

我遇到了同样的问题,这是一个非常简单的解决方法。您只需在请求中将内容类型设置为“application/json”,否则您的 HTTP 请求没有被正确解释并导致这个奇怪的错误。

要解决此问题,您可以在原始帖子中调用 setHTTPMethod 之后添加以下行:

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

【讨论】:

以上是关于iOS NSJSONSerialization 嵌套 NSDictionary 作为 POST 请求序列化时的键的主要内容,如果未能解决你的问题,请参考以下文章

iOS:NSJSONSerialization:错误的代码或错误的 JSON 结构?

在 iOS 中使用 NSJSONSerialization 时是不是有数据限制?

iOS - OC - JSON 解析 - NSJSONSerialization

iOS - 在 Swift 中使用 NSJSONSerialization 解析 JSON 字典

iOS7 是不是有轻量级 JSON 到对象映射器(不是 RestKit 或 NSJSONSerialization)?

iOS 5 中的 NSJSONSerialization 类似于 c# 序列化到类