简体   繁体   English

如何在.plist中写入数据?

[英]How to write data in .plist?

I'm trying to save some comments in a plist, that's OK cause its just a prototype. 我正在尝试将一些评论保存在plist中,这没关系,因为它只是一个原型。 The problem is that i can read from plist but when I try to write and read after that, it throws an "array out of bounds" exception. 问题是我可以从plist中读取内容,但是当我尝试写入并读取之后,它会抛出“数组超出范围”异常。 I can't figure it out what I'm doing wrong here. 我无法弄清楚我在这里做错了什么。

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];

That works fine, then i try to read: 效果很好,然后我尝试阅读:

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


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

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

And it throws the exception. 并引发异常。

If I add the item manually to the plist, it works fine, i guess it means that my reading code its fine. 如果我将项目手动添加到plist,它可以正常工作,我想这意味着我的阅读代码很好。

Could it be the structure of my 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>

* Terminating app due to uncaught exception 'NSRangeException', reason: '-[__NSCFArray objectAtIndex:]: index (1) beyond bounds (1)' *由于未捕获的异常“ NSRangeException”而终止应用程序,原因:“-[__ NSCFArray objectAtIndex:]:超出范围(1)的索引(1)”

I added the "description" to the array before writing to the plist. 我在写入plist之前将“描述”添加到了数组中。 If i use the following code: 如果我使用以下代码:

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

The return is (null) 返回值为(空)

But if i use: 但是,如果我使用:

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

i can see the contents of the array, and its all working properly. 我可以看到数组的内容,并且它们全部正常工作。

The problem is: In both ways i cant write to the file, it keeps returning "NO". 问题是:在两种方式下我都无法写入文件,它一直返回“ NO”。 And i already checked the permissions 我已经检查了权限

You are trying to write the file into mainBundle . 您正在尝试将文件写入mainBundle Definitely not possible. 绝对不可能。 You will have to write the plist file to Documents or Application Support folder of the app. 您必须将plist文件写入应用程序的 DocumentsApplication Support文件夹。

Create File Path in Documents Directory : 在文档目录中创建文件路径:

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

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

Write to FilePath 写入FilePath

[plistArray writeToFile:aFilePath atomically:YES];

Read From FilePath 从FilePath读取

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

I see two problems with your code: 我发现您的代码有两个问题:

  1. (May or may not be a problem). (可能不是问题)。 If the file does not exist initially, the initWithContentsOfFile: selector will return nil, causing the rest of your code to be no-ops. 如果该文件最初不存在,则initWithContentsOfFile:选择器将返回nil,从而导致其余代码成为空操作。

  2. (Probably the cause). (可能是原因)。 You may not write to the bundle resources directory. 您可能无法写入捆绑资源目录。 Store your file in the Documents or Caches directory instead. 而是将文件存储在Documents或Caches目录中。

To locate your documents directory, use something like this: 要找到您的文档目录,请使用以下命令:

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

First of all, why are you writing a file into your bundle? 首先,为什么要将文件写入包中?

Then, to address your problem, check if you actually did write the file. 然后,要解决您的问题,请检查您是否确实写入了文件。

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

Also, log your array when you're read it using -(void)description to check the contents of the dictionary. 另外,在读取数组时,请使用-(void)description记录数组以检查字典的内容。

Edit 编辑

As you said that you're not writing to your plist. 正如您所说的,您不是在写plist。 For now, just create a test plist on your desktop. 现在,只需在桌面上创建一个测试列表即可。

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

If that still returns Not Written, then there's something wrong with your dictionary. 如果仍然返回“未写”,则您的词典有问题。 Which I doubt because it's just strings (Though they could be placeholders for asking your question on stackoverflow. The docs states that the classes in the dictionary must be of NSData, NSDate, NSNumber, NSString, NSArray, or NSDictionary). 我怀疑这是因为它只是字符串(尽管它们可能是在stackoverflow上问您问题的占位符。文档指出字典中的类必须是NSData,NSDate,NSNumber,NSNumber,NSString,NSArray或NSDictionary)。 If that says written though, I'm guessing it doesn't write to your bundle because of permissions, which then you have to change your plist location to somewhere else other than your bundle, which I highly recommend. 如果那是写的,那么我猜它由于权限而没有写到您的捆绑软件中,因此您必须将plist位置更改为捆绑软件以外的其他位置,我强烈建议您这样做。

如果仅将一项放在数组中,则在从数组中读取时显然应该使用索引0而不是1:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM