我一直在开发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%的时间内检索到的数据都是用数据填充的,但我的结果是空的。(正如你在图片上看到的那样。有人可以帮我吗?
编辑:我收到以下错误
Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (Garbage at end.) UserInfo=0x753e5c0 {NSDebugDescription=Garbage at end.}
答案 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