【问题标题】:NSJSONSerialization Not Working, NSUTF8StringEncoding Is WorkingNSJSONSerialization 不工作,NSUTF8StringEncoding 工作
【发布时间】:2014-03-11 12:50:23
【问题描述】:

我已经阅读了文档、教程和其他 Stack Q&A,我很想知道如何使用 NSUTF8StringEncoding 让我的 JSON 出现,但不使用 NSJSONSerialization - 这就是我需要将数据提取到NSDictionaryNSArray。我认为这是从我的 URL 返回的 NSData 格式的问题?

编辑这里是错误:Error Domain=NSCocoaErrorDomain Code=3840“无法完成操作。(Cocoa 错误 3840。)”(垃圾结束。) UserInfo=0x8aabc30

NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.sampleURL.com"]
                                          cachePolicy:NSURLRequestUseProtocolCachePolicy
                                      timeoutInterval:15.0];

NSMutableData* responseData = [NSMutableData dataWithCapacity: 0];

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {

    //this works, and have NSLog below
    responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSLog(@"string %@", responseString);

    [responseData appendData:data];
    responseData = [[NSMutableData alloc] initWithData:data];

     //this is null in NSLog
    NSError * error;
    NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data   options:NSJSONReadingMutableContainers|NSJSONReadingAllowFragments error:&error];

    NSLog(@"jsonDict dict %@",jsonDict); 
}

调试控制台:

 2014-03-11 07:41:58.233 WBPC[7845:a0b] string   {"id":"a1","session":"General","name":"Exhibitor Setup Begins","startTime":"0900","details":"9am Exhibitor Hall","png":"image","speaker1":"Johnson","speaker2":"Nelson","speaker3":""}{"id":"b1","session":"General","name":"Conference Registration","startTime":"1000","details":"10am Noon Upper Level Lobby","png":"image","speaker1":"Jackson","speaker2":"","speaker3":""}
 2014-03-11 07:41:58.236 WBPC[7845:a0b] jsonDict (null)

【问题讨论】:

  • NSMutableDictionary * json = [NSJSONSerialization JSONObjectWithData:data options: NSJSONReadingMutableContainers error: &error];试试这个
  • 我实际上尝试过那个(来自你们中的其他 Stack 帖子),但没有运气。我确信这是从 URL 返回的 JSON 的格式问题...
  • @NamoNamo - 这是我从 NSJSONSerialization 收到的错误:错误域 = NSCocoaErrorDomain 代码 = 3840“操作无法完成。(可可错误 3840。)”(垃圾结束。)用户信息=0x8aabc30。谢谢。

标签: ios json nsdata nsjsonserialization


【解决方案1】:

您在 'didReceiveData' 委托函数中完成这一切,这不是正确的位置。唯一应该存在的是:

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [self.responseData appendData:data];
}

但在此之前,您应该在连接收到响应时初始化“self.responseData”:

-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    if(self.responseData != nil) self.responseData = nil;
    self.responseData = [[NSMutableData alloc] init];
}

然后,您需要实现另一个名为“connectionDidFinishLoading”的委托函数,当调用此方法时,您的“responseData”将包含来自 JSON 的所有数据并准备好解析:

-(void)connectionDidFinishLoading:(NSURLConnection *)connection {

     responseString = [[NSString alloc] initWithData:self.responseData encoding:NSUTF8StringEncoding];

     NSLog(@"string %@", responseString);

     NSError * error;
     NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers|NSJSONReadingAllowFragments error:&error];

     NSLog(@"jsonDict dict %@",jsonDict); 
}

我希望这在某种程度上有所帮助。

【讨论】:

  • 感谢分享。实际上,我确实使用了这些委托方法,我只是出于说明目的简化了我的示例。
  • 除了上面已经显示的之外,在委托方法connection: didReceiveResponse: 中应该检查HTTP 状态代码和响应数据的类型(MIME 类型)。如果状态码指示错误,我们无论如何都应该读取响应,以便从服务器获取可能的“错误消息”。在connectionDidFinishLoading: 中,我们再次使用 HTTP 状态码来决定是否应该记录错误消息或根据 MIME 类型处理预期的响应数据。
【解决方案2】:

您的 JSON 格式不正确。您告诉我们它是(为便于阅读而添加了空格和换行符):

{
    "id": "a1",
    "session": "General",
    "name": "Exhibitor Setup Begins",
    "startTime": "0900",
    "details": "9am Exhibitor Hall",
    "png": "image",
    "speaker1": "Johnson",
    "speaker2": "Nelson",
    "speaker3": ""
}{
    "id": "b1",
    "session": "General",
    "name": "Conference Registration",
    "startTime": "1000",
    "details": "10am Noon Upper Level Lobby",
    "png": "image",
    "speaker1": "Jackson",
    "speaker2": "",
    "speaker3": ""
}

这在两个字典条目之间缺少逗号,并且您缺少应该包装 JSON 的 []。如果它真的是一个字典条目数组,它应该是:

[
    {
        "id": "a1",
        "session": "General",
        "name": "Exhibitor Setup Begins",
        "startTime": "0900",
        "details": "9am Exhibitor Hall",
        "png": "image",
        "speaker1": "Johnson",
        "speaker2": "Nelson",
        "speaker3": ""
    },
    {
        "id": "b1",
        "session": "General",
        "name": "Conference Registration",
        "startTime": "1000",
        "details": "10am Noon Upper Level Lobby",
        "png": "image",
        "speaker1": "Jackson",
        "speaker2": "",
        "speaker3": ""
    }
]

如果你想检查你的 JSON,你可以访问http://jsonlint.com。此外,如果您检查了 JSONObjectWithData 返回的 error 对象,它会为您指明正确的方向。

您应该看看这个 JSON 是如何生成的。看起来它必须是手动生成的。例如,如果您从 PHP 页面生成此文件,则应使用 json_encode,而不是手动生成 JSON。


顺便说一句,您正在尝试解析didReceiveData 中的结果。在connectionDidFinishLoading 之前,您不应该尝试解析。您的 didReceiveData 应该仅将 data 附加到您的 NSMutableData 对象。解析应该推迟到connectionDidFinishLoading

【讨论】:

  • 问题在于我的 PHP 是如何输出 JSON 的,我需要将它包装在这样的数组中: $output = array();而 ($list = mysql_fetch_assoc($query)){ $output[] = $list; } echo json_encode($output);
【解决方案3】:

你好,你可以试试这个。

NSError *error = nil;
NSArray *jsonResponseArray = [NSJSONSerialization JSONObjectWithData: YOURDATA options: NSJSONReadingMutableContainers error: &error];

if (!jsonResponseArray) {
  NSLog(@"Error: %@", error);
} else {
   for(NSDictionary *dic in jsonResponseArray) {
      NSLog(@"dic values are : %@", item);
   }
}

谢谢

【讨论】:

  • 不幸的是我也试过这个,但没有运气。
【解决方案4】:

您发布的 JSON 字符串不是有效的 JSON。仅仅因为数据是有效的 UTF8 字符串并不意味着它一定是 JSON。尝试将调试后的字符串粘贴到 JSONLint 中,它会显示您的 JSON 对象之间缺少逗号。

【讨论】:

  • 当然 JSON 可以是 UTF-16 或 UTF-32,所以有效的 JSON 不需要是有效的 UTF8 字符串。
猜你喜欢
  • 1970-01-01
  • 2016-03-05
  • 2019-01-19
  • 1970-01-01
  • 2021-01-10
  • 2018-12-22
  • 2016-04-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多