返回

iOS 使用 NSMutableURLRequest 发送递归 JSON 请求

IOS

iOS 中使用 NSMutableURLRequest 发送递归 JSON 请求

在使用 iOS 开发中,经常需要向服务器发送包含 JSON 数据的请求。NSMutableURLRequest 提供了强大的网络请求功能,但处理嵌套 JSON 数据时,可能会遇到一些挑战。这篇文章讨论如何使用 NSMutableURLRequest 构建并发送递归 JSON 请求。

问题:如何构建复杂的嵌套 JSON 数据

一个常见的情形是,服务器期望的 JSON 数据具有嵌套结构,如示例中的 “post” 结构:

{
    "post": {
        "title": "string",
        "room_id": "int",
        "content": "string"
    }
}

直接拼接字符串难以构建这种结构,并且容易出错。使用 NSJSONSerialization 序列化 NSDictionary 对象成为 JSON 数据,再将这个 NSData 对象赋值给 NSMutableURLRequest 的 HTTPBody,是一种更安全可靠的方法。

解决方案 1:使用 NSJSONSerialization 进行序列化

iOS SDK 提供的 NSJSONSerialization 类,能够方便地将 NSDictionaryNSArray 对象转换为 JSON 格式的 NSData 数据,或者反向转换。这正是解决递归 JSON 结构问题的关键。

操作步骤:

  1. 构建 NSDictionary 对象:
    使用字典(NSDictionary)或数组(NSArray)来表示你希望发送的 JSON 结构。键值对中的键对应 JSON 对象中的 key, 值可以是字符串、数字、另一个字典,或者是数组,以此实现递归结构。

  2. 序列化为 NSData
    利用 NSJSONSerialization 将构建好的字典转换为 NSData,便于传输。NSJSONWritingPrettyPrinted 可以用于格式化输出的 JSON 数据(主要方便调试),正式环境下可移除此选项以减小数据大小。

  3. 设置 NSMutableURLRequest 的 HTTP Body:
    将序列化得到的 NSData 对象,通过 setHTTPBody: 方法设置给请求对象的 HTTP body 属性。同时需要正确设置 Content-TypeContent-Length

代码示例:

NSString *usertoken = @"your_auth_token"; // 替换为真实的 auth token
NSString *posttopic = @"example_title";
NSString *postbody = @"example_content";
int roomID = 123;

NSDictionary *postDict = @{@"title": posttopic, @"room_id": @(roomID), @"content": postbody};
NSDictionary *requestDict = @{@"post": postDict};


NSError *error;
NSData *body = [NSJSONSerialization dataWithJSONObject:requestDict options:0 error:&error];


if (error) {
  NSLog(@"Error serializing JSON: %@", error.localizedDescription);
  return;
}
  

NSString *postLength = [NSString stringWithFormat:@"%lu", (unsigned long)[body length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];

NSString *urlstring = [NSString stringWithFormat:@"http://mydomain.example.com/posts.json?auth_token=%@", usertoken];

[request setURL:[NSURL URLWithString:urlstring]];
[request setHTTPMethod:@"POST"];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; // 设置为 "application/json"
[request setHTTPBody:body];

// 发送请求(此处使用同步请求,请在实际项目中考虑使用异步请求)
NSURLResponse *response;
NSData *POSTReply = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];


if(error){
        NSLog(@"Request Error: %@", error.localizedDescription);
        
        
        return;
 }


  // 解析响应数据,错误处理等(省略)

关键点:

  • 设置正确的内容类型 (Content-Type): 务必设置 Content-Typeapplication/json, 通知服务器此请求的内容是 JSON 数据。如果使用 application/x-www-form-urlencoded 会导致数据解析失败。

安全建议

  • 错误处理: 在进行 NSJSONSerialization 和发送网络请求时,请务必处理 NSError 对象,避免因错误导致程序崩溃。
  • HTTPS: 实际应用中,始终建议使用 HTTPS 加密你的网络请求,确保数据的传输安全。
  • 数据校验: 确保你发送的数据结构和类型符合服务器的预期。

总结

使用 NSJSONSerialization 处理 JSON 数据,是处理 iOS 应用中复杂 JSON 数据请求的最佳实践。 它能避免手动字符串拼接的错误,并保证数据的正确性和可靠性。正确地设置请求头中的 Content-Type 对于确保服务器正确解析请求数据至关重要。通过采用以上方法,能显著提高构建和发送 JSON 请求的效率与稳定性。