如何在.plist中写入数据?

时间:2012-07-26 11:54:40

标签: objective-c ios plist nsdictionary

我试图在plist中保存一些评论,这可以使它只是一个原型。问题是我可以从plist中读取,但是当我尝试写入和读取之后,它会抛出一个超出界限的数据"例外。我无法弄清楚我在这里做错了什么。

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Comments" ofType:@"plist"];
NSMutableArray *plistArray = [[NSMutableArray alloc] initWithContentsOfFile:filePath];


NSMutableDictionary *newComment = [NSMutableDictionary dictionary];
[newComment setValue:commentTitle.text forKey:@"title"];
[newComment setValue:comment forKey:@"comment"];


[plistArray addObject:newComment];
[plistArray writeToFile:filePath atomically:NO];

工作正常,然后我尝试阅读:

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Comments" ofType:@"plist"];
NSMutableArray *plistArray = [[NSMutableArray alloc] initWithContentsOfFile:filePath];


NSMutableDictionary *dictionary = (NSMutableDictionary *) [plistArray objectAtIndex:0];

NSLog(@"%@", [dictionary objectForKey:@"title"]);

它抛出异常。

如果我手动将项目添加到plist,它工作正常,我想这意味着我的阅读代码很好。

这可能是我的plist的结构吗?

<?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 <plist version="1.0">
 <array>
 </array>
 </plist>

* 由于未捕获的异常终止应用&#39; NSRangeException&#39;,原因:&#39; - [__ NSCFArray objectAtIndex:]:index(1)超出bounds(1)&# 39;

我添加了&#34;描述&#34;在写入plist之前到数组。如果我使用以下代码:

NSString *aDocumentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
//    NSString *aFilePath = [NSString stringWithFormat:@"%@/Comments.plist", aDocumentsDirectory];
//
//    NSMutableArray *plistArray = [[NSMutableArray alloc] initWithContentsOfFile:aFilePath];

返回值为(null)

但如果我使用:

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Comments" ofType:@"plist"];
NSMutableArray *plistArray = [[NSMutableArray alloc] initWithContentsOfFile:filePath];

我可以看到数组的内容,并且它们都能正常工作。

问题是:在两种方式中我都无法写入文件,它会一直返回&#34; NO&#34;。我已经检查了权限

4 个答案:

答案 0 :(得分:3)

您正在尝试将文件写入 mainBundle 。绝对不可能。 您必须将plist文件写入应用程序的文档应用程序支持文件夹。

在文档目录中创建文件路径:

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

NSString *aFilePath = [NSString stringWithFormat:@"%@/Comments.plist", aDocumentsDirectory];

写入FilePath

[plistArray writeToFile:aFilePath atomically:YES];

从FilePath读取

NSMutableArray *plistArray = [[NSMutableArray alloc] initWithContentsOfFile:aFilePath];

答案 1 :(得分:0)

我发现您的代码有两个问题:

  1. (可能是也可能不是问题)。如果该文件最初不存在,initWithContentsOfFile:选择器将返回nil,导致其余代码为no-ops。

  2. (可能是原因)。您可以写入捆绑资源目录。将文件存储在Documents或Caches目录中。

  3. 要找到您的文档目录,请使用以下内容:

    - (NSString*) pathForDocument:(NSString*)documentName {
        NSArray *documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        if(documentDirectories.count < 1) return nil;
        return [[documentDirectories objectAtIndex:0] stringByAppendingPathComponent:documentName];
    }
    

答案 2 :(得分:0)

首先,你为什么要在你的包中写一个文件?

然后,为了解决您的问题,请检查您是否确实写了该文件。

if ([plistArray writeToFile:filePath atomically:NO])
    NSLog (@"Written");
else
    NSLog (@"Not Written");

此外,当您使用-(void)description读取数组时,请记录您的数组以检查字典的内容。

修改

正如你所说,你不是在写你的plist。现在,只需在桌面上创建一个测试plist。

NSString *testPath = [[NSString stringWithString:@"~/Desktop/Comments.plist"] stringByExpandingTildeInPath];
if ([plistArray writeToFile:testPath atomically:NO])
    NSLog (@"Written");
else
    NSLog (@"Not Written");    

如果仍然返回Not Written,那么你的字典出了问题。我怀疑它是因为它只是字符串(尽管它们可能是在stackoverflow上提出问题的占位符。文档声明字典中的类必须是NSData,NSDate,NSNumber,NSString,NSArray或NSDictionary)。如果说写了,我猜它不会写入你的捆绑,因为权限,然后你必须将你的plist位置改为除你的捆绑以外的其他地方,我高度推荐。

答案 3 :(得分:-2)

如果您只在数组中放入一个项目,那么在读取数据时,您应该使用索引0而不是1:

NSMutableDictionary *dictionary = (NSMutableDictionary *) [plistArray objectAtIndex:0];