NSJSONSerialization 弄乱了结果 NSDictionary
Posted
技术标签:
【中文标题】NSJSONSerialization 弄乱了结果 NSDictionary【英文标题】:NSJSONSerialization messing up resulting NSDictionary 【发布时间】:2014-08-22 09:32:09 【问题描述】:我在解析来自 Web 服务的 json 输出时遇到问题。我正在使用 NSJSONSerialization 将输出解析为 NSDictionary。还通过子类化 AFHTTPSessionManager 来使用 AFNetworking。现在响应序列化器是 AFHTTPResponseSerializer 它返回 NSData 这是我正在使用的代码:
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableLeaves error:&err];
非常简单。并且 err 对象为零,因此转换工作正常。
但是:我直接从网络服务得到的结果是这样的:
"address":
"address1": "Ivy House",
"address2": "Sandy Lane",
"city": "Rush",
"postCode": null,
"email": "notknown@whatever.com",
"telephone": "18437584",
"mobile": null,
"smsAlert": null,
"county": "Dublin",
"country": "Ireland",
"websiteAddress": "www.example.com"
,
打印dict的内容后得到的结果是这样的:
address =
address1 = "Ivy House";
address2 = "Sandy Lane";
city = Rush;
country = Ireland;
county = Dublin;
email = "notknown@whatever.com";
mobile = "<null>";
postCode = "<null>";
smsAlert = "<null>";
telephone = 18437584;
websiteAddress = "www.example.com";
;
问题是生成的 NSDictionary 没有双引号,因此将 NSDictionary 以 plist 格式保存到磁盘失败!
我也尝试过使用 AFJSONResponseSerializer,它返回 NSDictionary 但内容和上面一样!
问题出在哪里?
提前致谢。
【问题讨论】:
您的示例中缺少双引号只是因为这是打印 NSDictionary(甚至可能是 NSString)的方式。如果将此字典保存到属性列表失败,那么这是由于另一个原因(您可以使用[NSPropertyListSerialization dataWithPropertyList:format:options:error:]
中的error
进行跟踪。
我同意@Andrey。似乎 NSDictionary 描述没有为仅包含字母数字字符(没有分隔符)的字符串添加引号。
@Andrey 我无法保存到 plist,所以我无法再次尝试阅读。即使 URL 完全有效,writeToURL:atomically: 也会返回 NO。文档说如果返回为 NO 那么这是因为字典没有正确形成(此方法在写出之前递归地验证所有包含的对象都是属性列表对象(NSData、NSDate、NSNumber、NSString、NSArray 或 NSDictionary 的实例)文件,如果所有对象都不是属性列表对象,则返回 NO,因为结果输出不是有效的属性列表。)
您可以使用dataWithPropertyList:format:options:error:
找出错误。它与双引号无关。我认为那些nulls
可能是保存到 plist 失败的真正原因。
我使用了 propertyListWithData:options:format:error: 这是我得到的错误:Error Domain=NSCocoaErrorDomain Code=3840 "The operation could not be completed. (Cocoa error 3840.)" ( Unexpected character at line 1) UserInfo=0x8e81b20 NSDebugDescription=Unexpected character at line 1, kCFPropertyListOldStyleParsingError=操作无法完成。 (可可错误 3840。)
【参考方案1】:
这里的问题似乎根本与双引号无关。打印时,NSDictionary
(以及其他 Foundation 对象)在不需要时(例如,当字符串中没有空格或特殊字符时)删除包含双引号的双引号。
现在,阻止您将NSDictionary
序列化为属性列表的可能问题是在 JSON 中存在 nulls
,因此在 NSDictionary
中存在。根据documentation:
属性列表对象包括
NSData
、NSString
、NSArray
、NSDictionary
、NSDate
和NSNumber
对象。
而来自 JSON 的 nulls
将表示为 NSNull
的实例,从而使您的 NSDictionary
成为无效的属性列表。
【讨论】:
【参考方案2】:NSDictionary 的结构与 JSON 字符串不同。因此,当您将 JSON 字符串解析为 NSDictionary 时,您不应该期望引号。
您可以保存 JSON 数据并在运行时再次对其进行解析。
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:@"yourfilename.dat"];
// Save it into file system
[data writeToFile:dataPath atomically:YES];
【讨论】:
我回到使用 AFHTTPResponseSerializer 并且 responseObject 现在是 NSData 类型。这是我的代码: NSString *filePath = [[self applicationCacheDirectory] stringByAppendingPathComponent:@"yourfilename.dat"]; BOOL save = [responseData writeToFile:filePath atomically:YES];立即保存返回 YES!我可以再次将数据文件读入 NSDictionary。所以这看起来是一个很好的解决方法以上是关于NSJSONSerialization 弄乱了结果 NSDictionary的主要内容,如果未能解决你的问题,请参考以下文章
为啥 QTextBrowser 弄乱了我的 HTML 代码?