将 JSON 响应写入 .plist 文件

Posted

技术标签:

【中文标题】将 JSON 响应写入 .plist 文件【英文标题】:Write JSON Response to .plist File 【发布时间】:2013-03-20 14:17:24 【问题描述】:

顶部的挫败感!!!

我从服务中获得了一些 JSON 响应,我想将其存储在 .plist 文件 中以供将来参考。 我无法将我的 JSON 响应保存到 .plist 文件。我认为这是由于响应中有一些 null 值。

注意: 我确认响应是 JSON 格式 使用 jsonparser。


我的代码:

NSError *error;
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
NSDictionary *dictResult = [(NSDictionary*)json objectForKey:@"myKey"];
NSLog(@"Result Dictionary :: %@",dictResult);

NSURL *cacheDir = [[[NSFileManager defaultManager] URLsForDirectory:NSCachesDirectory inDomains:NSUserDomainMask] lastObject];
NSURL *path = [cacheDir URLByAppendingPathComponent:@"FinalResult.plist"];
NSLog(@"Path :: %@",path);

BOOL success = [dictResult writeToURL:path atomically:YES];
NSLog(@"success? %d", success);

注意: 我得到了所有 NSLog 值(表示响应字典文件路径0 表示成功


问题:响应中几乎有 70-80 个键值对,我不想全部删除/替换 null 值。因为我想要的是……

    从服务器获取响应。 用响应填充所有 UITextFields。 使用 UITextFields 中的一些编辑值向服务器发布相同的响应。

所以,我只想更改 Object 中 Edited UITextField 的值,然后让它 POST 到服务器。

解决此问题的最佳方法是什么?

【问题讨论】:

JSON 字典包含哪些类型的数据?字符串,数字,还有什么?您可以将 JSON 添加到您的问题中吗? @TomHarrington:我的 JSON 字典包含您在答案中提到的几乎所有类型的值。 【参考方案1】:

我敢打赌,您的 JSON 至少包含一个 null 值。

当您拥有包含 null 的 JSON 并使用 NSJSONSerialization 对其进行转换时,null 将替换为 NSNull 的实例。如果您的字典包含NSNull,那么writeToURL:atomically: 将失败。

这是因为读取和写入字典(和数组)的便捷方法仅在集合中的数据仅限于属性列表类型时才有效。它们是:

NSString NSNumber NSData NSDate NSArray NSDictionary。对于字典,键必须是NSStrings。

您也可以在编写时使用可变子类(如NSMutableString)。

如果您有任何不在该列表中的内容,则不能使用writeToURL:atomically 或任何类似的便捷方法。

问题是某些有效的 JSON 无法转换为属性列表。此外,一些有效的属性列表无法转换为 JSON(因为NSDate 不会自动转换为有效的 JSON)。

如果是我,我只会将数据写入 JSON 文件。保留其原始格式。您可以轻松地与 JSON 进行转换,因此请保持这种状态。

【讨论】:

+1。是的,你是绝对正确的。我的 JSON 响应中有一些 值。那么该怎么办呢? 就像我说的,我认为最好的办法是将数据保留为 JSON 并将其写入文件,而不是尝试使用属性列表。如果必须使用属性列表,则需要扫描整个字典并将空值转换为可以保存在属性列表文件中的内容。 我想说的不仅仅是“我同意”,所以我会支持@TomHarrington 所说的话,提到我确实有一个应用程序可以将 json 转换为 PropertyList 以便可以编写它到 NSUserDefaults。为此,JSON 响应中 值的唯一解决方案是一一识别它们,而不是转换它们/不写出它们。 @TomHarrington:我想用 Response 中的值更改 EDITED 值...我认为您的建议是不可能的。如果我将数据保留为 JSON 并将其写入文件,那么它就无法以我想要的方式更新。 @Vin 然后就像我说的那样,您需要扫描您的 JSON 以查找并消除任何无效的 n 属性列表。【参考方案2】:

如果您的字典包含NSNull,那么writeToURL:atomically: 将失败。

对于字典,键必须是 NSStrings

问题是某些有效的 JSON 无法转换为属性列表。此外,某些有效的属性列表无法转换为 JSON

别忘了,如果必须使用属性列表,则需要扫描整个字典并将空值转换为可以保存在属性列表文件中的内容。

唯一的解决方案是您必须检查所有 NULL 值并将其替换为 @" "

快乐编码...

【讨论】:

【参考方案3】:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *libraryPath = [paths objectAtIndex:0];
NSString *filename = @"FinalResult.plist";
NSString *pathFilename = [libraryPath stringByAppendingPathComponent:filename];

NSDictionary *dictResult = [json objectForKey:@"myKey"];
[dictResult writeToFile:pathFilename atomically:YES];

【讨论】:

这不是问题,我的朋友。你检查过汤姆哈灵顿的答案吗? @Vin 你已经说过,你无法将数据保存到 plist,我的回答是,“Tom Harrington”已经解释了你可以在 plist 中保存什么类型的对象 您的回答中没有说明我无法将数据保存到 plist 的原因。 好吧,因为你正在创建文件路径 URL,你只需要 filePath 来存储它 如果你必须用 URL 保存然后使用这个 [dict writeToURL:path atomically:YES];【参考方案4】:

我以这种方式构建我的文件网址:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *path = [paths objectAtIndex:0];
NSString *filename = @"FinalResult.plist";
NSString *pathFilename = [path stringByAppendingPathComponent:filename];

然后看看是不是这样写的:

BOOL success = [dictResult writeToFile:pathFilename atomically:YES];
NSLog(@"success? %d", success);

编辑 - 有趣的是,我最近才遇到这个问题,然后就忘记了。一些 JSON 解析器将使用 [NSNull null] 作为 nil 值的占位符。我写了这个(说真的,大约两周前,然后在上面隔开)来清理解析结果......

- (NSDictionary *)compact:(NSDictionary *)aDictionary 

    NSDictionary *answer = [NSMutableDictionary dictionary];

    for (NSString *key in [aDictionary allKeys]) 
        id value = [self.dictionary valueForKey:key];
        if (value && value != [NSNull null]) 
            [answer setValue:value forKey:key];
        
    
    return [NSDictionary dictionaryWithDictionary:answer];

如果您愿意,可以将其添加到 NSDictionary 类别中。

【讨论】:

我得到了路径,但没有创建 .plist 文件。 @Vin 可以只用一个字符串键和值来构建你自己的字典,看到那写了吗?既然你从 Jason 那里得到了字典,我想这里的每个人都假设它是可序列化的,但让我们开始运行吧。一个简单的字典写得正确会告诉我们很多。 @danh:它与简单的字典完美配合。问题是由于 Tom 所说的 JSON 响应中的一些 值,我想是的。 @danh:你检查过我的问题中的“其他问题”部分吗? @Vin。我无法解释(包括 NSNull 理论)。以防万一,我添加了我最近编写的代码来清理 JSON 解析。崩溃似乎预示着更糟糕的事情。你能粘贴一个 NSLog(@"%@", dictResult);还是那也会崩溃?【参考方案5】: 检查writeToURL:atomically:方法的返回值是否返回YES。 如果没有,请检查您是否对该 URL 具有写入权限。 尝试使用另一个 URL 来确定是它的路径还是字典的内容导致了这个错误。

【讨论】:

【参考方案6】:

试试这个,它会起作用的:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"country.plist"];
[jsonData writeToFile:path atomically:YES];

【讨论】:

以上是关于将 JSON 响应写入 .plist 文件的主要内容,如果未能解决你的问题,请参考以下文章

关于将布尔文件写入 plist

将 NSArray 写入 plist 文件

Swift 3:无法将数据写入 plist 文件

如何将 NSMutableDictionary 写入 Plist

如何将 JSON **text** 写入 Excel 文件?

如何成功写入plist?