如何在 xcode 5 iOS 7 中以编程方式编辑 plist?

Posted

技术标签:

【中文标题】如何在 xcode 5 iOS 7 中以编程方式编辑 plist?【英文标题】:how to edit a plist programmatically in xcode 5 iOS 7? 【发布时间】:2014-04-08 23:06:04 【问题描述】:

如何编辑或更改值字符串:

在这个 plist 中,我需要在第 2 项的启用值中更改或设置“否”,我看到很多示例,但不起作用,或已弃用,或不使用 ARC,有什么想法或示例代码吗?请大家帮忙

EDIT#1:我试试这个(不工作)

 NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    path = [path stringByAppendingPathComponent:@"List.plist"];

    NSFileManager *fileManager = [NSFileManager defaultManager];
    if (![fileManager fileExistsAtPath:path]) 
        NSString *sourcePath = [[NSBundle mainBundle] pathForResource:CONTENT_DEFAULT ofType:PLIST];
        [fileManager copyItemAtPath:sourcePath toPath:path error:nil];
    

    NSArray*  newContent = [[NSArray alloc]initWithContentsOfFile:path];
    NSDictionary *Dict = [[NSDictionary alloc]initWithDictionary:[newContent objectAtIndex:2]];
     [Dict setValue:@"NO" forKey:@"Enabled"];
      [Dict writeToFile:path atomically:YES];

注意:不工作,它崩溃发送给我:

*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<__NSDictionaryI 0x15de7ff0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key Enabled.', or Im wrong in something?

编辑 #2 新尝试

NSString *path = [[NSBundle mainBundle] pathForResource:@"List" ofType:@"plist"];

    NSString *savingPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];

    NSArray*  newContent = [[NSArray alloc]initWithContentsOfFile:path];
    NSMutableDictionary *Dict = [[NSMutableDictionary alloc]initWithDictionary:[newContent objectAtIndex:2]];
    [Dict setValue:@"NO" forKey:@"Enabled"];
    savingPath = [savingPath stringByAppendingPathComponent:@"Modified.plist"];
    [Dict writeToFile:savingPath atomically:YES];

    NSLog(@"newContent:%@",newContent);
    NSArray *newnew = [[NSArray alloc]initWithContentsOfFile:savingPath];
    NSLog(@"newnew:%@",newnew);

注意:现在给我打印一个崩溃:

*** Terminating app due to uncaught exception 'NSRangeException', reason: '-[__NSCFArray objectAtIndex:]: index (3) beyond bounds (2)'

【问题讨论】:

你怎么知道它不起作用?您不会在 Xcode 内置编辑器中看到更改。顺便说一句,它应该是[newContent objectAtIndex:3],而不是 2。 感谢 Sergius,我确实编辑了有关崩溃的问题 变量 *dict 应该是NSMutableDictionary。并尝试NSLogging 它 - 用输出更新我们。 感谢 Sergius,现在不会崩溃,但不会更改我 plist 中的任何内容 I NSLogging but print me (null) 也许是路径,但我该如何解决这个问题? 【参考方案1】:

您所要做的就是使用NSMutableDictionary 而不是常规字典来修改内容。您必须始终检查您正在编辑的对象是否存在。

要获得您在Xcode 中创建的 plist 的正确路径,您需要使用:

NSString *path = [[NSBundle mainBundle] pathForResource:@"List" ofType:@"plist"];

您实际上可能希望将该文件保存到应用程序的文档目录中。因此,您将使用以下路径来保存内容:

NSString *savingPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
savingPath = [savingPath stringByAppendingPathComponent:@"Modified.plist"];
[Dict writeToFile:savingPath atomically:YES];

【讨论】:

感谢 Sergius,我需要创建一个名为“Modified.plist”的新 plist?或者这保存在同一个“List.plist”中,因为,我确实尝试了这两种方法,但没有保存或编辑 plist @user_Dennis_Mostajo 这很奇怪。你必须NSLog给定的plist,看看它在那里,然后编辑它并将它保存到一个新文件中。您无法将 plist 保存到应用程序包中,您不会在 Xcode 中看到它!看看 - ***.com/questions/5674011/… 我尝试保存在一个新的 plist 中,但现在给我打印一个崩溃日志:*** 由于未捕获的异常 'NSRangeException' 导致应用程序终止,原因:'-[__NSCFArray objectAtIndex:]: index (3 ) 越界 (4)'【参考方案2】:

好吧,在您的情况下,解决方案如下(当您将 Dictionary 作为 Array 的成员时):

NSString *path = [[NSBundle mainBundle] pathForResource:@"List" ofType:@"plist"];
NSArray *newContent = [[NSArray alloc]initWithContentsOfFile:path];
//iterating through all members since all of them has the string "YES" which should be replaced, otherwise, you will need to create a separate dictionary for each member
for ((i = 0; i < [newContent count]; i++))
//here you take the member (dictionary) of the array
    NSDictionary *dictOfArray = [newContent objectAtIndex:i];
    [dictOfArray objectForKey:@"Enabled"]=@"NO";
    
//if you update the same pList you can use the same path (otherwise use another path)
[newContent writeToFile:path atomically:YES];

所以,它现在可以工作了。

【讨论】:

以上是关于如何在 xcode 5 iOS 7 中以编程方式编辑 plist?的主要内容,如果未能解决你的问题,请参考以下文章

在 xcode/ios 中以编程方式编辑 RTF/DOC 文件

如何在 Swift 5 中以编程方式在特定屏幕(即主显示器而不是外部显示器)上显示窗口? [苹果系统; Xcode 15]

如何在 iOS 7 中以编程方式正确关闭 UIAlertView?

iOS 7 / Xcode 5:以编程方式访问设备启动图像

如何在iOS 7中以编程方式设置设备方向?

在 Xcode 5 中以编程方式修改 UINavigationcontroller