【问题标题】:NSJSONSerialization JSONObjectWithData returns NSStringNSJSONSerialization JSONObjectWithData 返回 NSString
【发布时间】:2013-12-13 19:24:05
【问题描述】:

我有一个 NSJSONSerialization JSONObjectWithData,我在其中传递了一个 NSData 对象。结果,我得到了一个 NSString 而不是 NSDictionary。我的完整行是:

NSDictionary* jsonDec = [NSJSONSerialization JSONObjectWithData:jData options:NSJSONReadingAllowFragments error:&error];

而回报是:

为什么我没有返回一个 NSDictionary?我的后端是服务器上的PHP...

提前致谢!

【问题讨论】:

  • 原始 JSON 长什么样?您的服务器肯定没有意外编码两次并返回一个字符串对象? NSJSONSerialization 通常应该返回一个字典或一个数组,如果你已经设置了 NSJSONReadingAllowFragments,它也会很高兴地返回一个原始类型,如果这是它找到的全部。
  • 即字典的字符串表示。你可以这样做: NSLog(@"%@",jsonDec);并且会在控制台日志中将 dict 视为字符串。
  • 原因:'-[__NSCFString objectForKey:]:发送到实例的选择器无法识别。如果我尝试执行以下操作,这是我得到的错误:[[jsonDec objectForKey:@"result"] valueForKey:@"UserID"]
  • @Cyber​​K:在我看来,您的服务器正在发送“嵌套 JSON”(无论出于何种原因)。比较 stackoverflow.com/questions/16948427/… 的类似问题,也许你可以使用它。
  • 问题出在服务器上,它正在发送两次编码的 JSON;尝试在此处发布您正在使用的 PHP 代码。

标签: ios xcode


【解决方案1】:
NSDictionary *jsonDec;
NSError* error = nil;
jsonDec = [NSJSONSerialization JSONObjectWithData: jData
                                          options: NSJSONReadingMutableContainers
                                            error: &error];

if (error)
{
     NSLog(@"Error: %@",error);
}

Apple 文档:NSJSONReadingMutableContainers - 指定将数组和字典创建为可变对象。

【讨论】:

  • Error Domain=NSCocoaErrorDomain Code=3840 “操作无法完成。(Cocoa 错误 3840。)”(JSON 文本没有以数组或对象开头,并且允许未设置片段的选项。) UserInfo=0x10d25c950 {NSDebugDescription=JSON 文本没有以数组或对象开头,并且允许未设置片段的选项。}
  • 你要序列化的变量
  • NSString *decodedString = [[NSString alloc] initWithData:decMutData encoding:NSUTF8StringEncoding]; NSData *jData = [NSData dataFromBase64String:decodedString];
  • 你搞砸了编码。
  • 这是为什么呢?我搞砸了什么?
【解决方案2】:

我在使用 JSON 响应时使用它(我的通常是字典数组)。我更喜欢使用对象类型id,只使用自省来确定它是NSArray 还是NSDictionary。顺便说一句 - 我的 Web 请求是使用 AFNetworking (v2) 或使用 Azure SDK 完成的。

id jsonDec = [NSJSONSerialization JSONObjectWithData:jData options:0 error:&error];

【讨论】:

  • 你的答案和我的有什么不同?
  • 好吧,您将序列化的对象分配给NSDictionary,这在大多数情况下是一个错误。除非您知道您的所有响应都是 JSON 字典,否则您应该使用 id 然后找出您拥有的内容。我的大部分请求最终都以NSArray 的字典形式出现。您还可以使用该选项创建可变对象,但效率不如使用不可变对象。
  • 顺便说一句 - 我没有否决你的答案。我真的希望当人们对一个答案投反对票时,这个人也能留下评论来解释原因。
  • id 给我的结果与我写 NSDictionary 的结果完全相同
  • 虽然这是一种合理的做法,但我认为这与 OP 遇到的问题没有任何关系。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多