NSJSONSerialization有时在异步请求中返回null

时间:2013-01-24 10:44:56

标签: ios request nsjsonserialization

我一直在开发app,它会对JSON类型的数据进行异步请求。最近,我在代码中发现了一些奇怪的错误,我无法分辨它为什么会发生。

好的代码!

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

NSError *error=nil;

    result = [NSJSONSerialization JSONObjectWithData:retrievedData options:kNilOptions error:&error];
        NSLog(@"Result %@",result);
        NSLog(@"Retrieved data %@",retrievedData);
}

结果是NSDictionary,retrieveData是NSMutableData。 99%的时间,它工作正常,connectionDidFinishLoading被调用,我的结果被填充。但是,在1%的时间内检索到的数据都是用数据填充的,但我的结果是空的。(正如你在图片上看到的那样。有人可以帮我吗?

Log

编辑:我收到以下错误

Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (Garbage at end.) UserInfo=0x753e5c0 {NSDebugDescription=Garbage at end.}

4 个答案:

答案 0 :(得分:3)

如果您首先查看错误,看看是否有任何错误指示,将会有所帮助。

<强> [编辑]
您的错误提到了原因:Garbage at end.

来自网络服务器的响应不是有效的JSON,它在输出的末尾包含无效字符。

答案 1 :(得分:2)

我有同样的问题。首先,查看未正确解析的数据 - 在我的情况下,我做了

NSString *str = [[NSString alloc] initWithData:retrievedData encoding:NSUTF8StringEncoding];

在我的情况下,原因是 - 如果服务器连续发送了几个socket.write() - 所有数据都在一个块中收到,比如

{first:json}{second:json}..

当然这不能解析为单个json,所以我必须引入分隔符,并将接收到的缓冲区拆分为正确的块。

答案 2 :(得分:1)

这有点晚了,但在我这样做之前没有任何在线工作:

NSString * dataInString = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];

NSRange range = [dataInString rangeOfString:@"}" options:NSBackwardsSearch];

if(range.location != NSNotFound)
    dataInString = [dataInString substringWithRange:NSMakeRange(0,range.location+1)];

从那以后一直都在工作。

答案 3 :(得分:0)

我遇到了同样的错误,问题是我的服务器在我的json响应中添加了一些额外的行,当我在浏览器中获得响应时,这不会出现。使用终端中的curl,您可以看到实际输出。 黑客是截断额外的字符。与json你有一个数组或字典。根据您的json结构,您可以使用代码(如上面的答案),但在第2行中查找注释

NSString * str = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
NSRange range = [str rangeOfString:@"}" options:NSBackwardsSearch]; // } for dictionary, ] for array

if(range.location != NSNotFound)
str = [str substringWithRange:NSMakeRange(0,range.location+1)];

一旦从垃圾数据中清除了字符串,就可以再次将其转换为数据。

    NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];

现在从这些数据中你可以得到你的数组或字典。

id jsonObject = [NSJSONSerialization
                 JSONObjectWithData:data
                 options:kNilOptions error:&error];  // i used id to be general, you can use array or dictionary structure or later cast this object to as per json