用词典修正一个plist

时间:2012-09-16 21:04:40

标签: objective-c ios xcode

如果Plist不存在,则将其复制到documents directory

如果它已存在,我想使用NSDictionarybundleArray的“姓名”键在NSDictionary中找到匹配的documentsArray

找到匹配项后,我想检查字符串中的更改,并在有更改时替换它们。

如果未找到匹配项,则表示必须将此词典添加到文档plist中。

这是我的代码:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[self managePlist];
return YES;
}

- (void)managePlist {

NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"Objects.plist"];
NSString *bundle = [[NSBundle mainBundle] pathForResource:@"Objects" ofType:@"plist"];
NSFileManager *fileManager = [NSFileManager defaultManager];

if (![fileManager fileExistsAtPath: path]) {
    [fileManager copyItemAtPath:bundle toPath:path error:&error];

} else {

    NSArray *bundleArray = [[NSArray alloc] initWithContentsOfFile:bundle];
    NSMutableArray *documentArray = [[NSMutableArray alloc] initWithContentsOfFile:path];

    BOOL updateDictionary = NO;
    for(int i=0;i<bundleArray.count;i++) {

        NSDictionary *bundleDict=[bundleArray objectAtIndex:i];

        BOOL matchInDocuments = NO;
        for(int ii=0;ii<documentArray.count;ii++)
        {
            NSMutableDictionary *documentDict = [documentArray objectAtIndex:ii]; 
            NSString *bundleObjectName = [bundleDict valueForKey:@"Name"];
            NSString *documentsObjectName = [documentDict valueForKey:@"Name"];
            NSRange range = [documentsObjectName rangeOfString:bundleObjectName options:NSCaseInsensitiveSearch];
            if (range.location != NSNotFound) {
                matchInDocuments = YES;
            }
            if (matchInDocuments) {

                if ([bundleDict objectForKey:@"District"] != [documentDict objectForKey:@"District"]) {
                    [documentDict setObject:[bundleDict objectForKey:@"District"] forKey:@"District"];
                    updateDictionary=YES;
                }
            }

            else {
                [documentArray addObject:bundleDict];
                updateDictionary=YES;
            }
        }
    }
    if(updateDictionary){
        [documentArray writeToFile:path atomically:YES];
    }

}

}

如果我现在运行我的应用程序,我收到此消息:'-[__NSCFDictionary setObject:forKey:]: mutating method sent to immutable object'

我该如何解决这个问题?

修复此问题后,您认为我的代码是否有效?

如果没有,我很乐意就如何做到这一点提出一些建议。我已经挣扎了一段时间,真的需要通过更正发布更新!非常感谢你的帮助。

3 个答案:

答案 0 :(得分:3)

据推测,documentDict实际上是不可变的。即使您将其分配给NSMutableDictionary,也无法准确描述基础数据。

NSMutableDictionary *documentDict = [documentArray objectAtIndex:ii];

应该是:

NSMutableDictionary *documentDict = [NSMutableDictionary dictionaryWithDictionary:[documentArray objectAtIndex:ii]];

无论您在何处编辑documentDict,请添加:

 [documentArray replaceObjectAtIndex:ii withObject:documentDict];

答案 1 :(得分:0)

当你从文件中读取一个plist时,会创建一个包含不可变子项的不可变字典/数组,所以你的

  NSMutableDictionary *documentDict = [documentArray objectAtIndex:ii]; 

行是谎言 - 你没有可变字典。要从plist创建可变对象,请查看CFPropertyListCreateWithData并指定kCFPropertyListMutableContainersAndLeaves作为可变性选项。

答案 2 :(得分:0)

这是我使用James Webster的答案的最终和正常工作的代码。感谢H2CO3以及贡献。

- (void)managePlist {
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"Object.plist"];
NSString *bundle = [[NSBundle mainBundle] pathForResource:@"Object" ofType:@"plist"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:path]) {
    [fileManager copyItemAtPath:bundle toPath:path error:&error];
} 
else 
{
    NSArray *bundleArray = [[NSArray alloc] initWithContentsOfFile:bundle];
    NSMutableArray *documentArray = [[NSMutableArray alloc] initWithContentsOfFile:path];

    BOOL updateDictionary = NO;
    for(int i=0;i<bundleArray.count;i++) {
        NSDictionary *bundleDict=[bundleArray objectAtIndex:i];            

        for(int ii=0;ii<documentArray.count;ii++)
        {
            NSMutableDictionary *documentDict = [NSMutableDictionary dictionaryWithDictionary:[documentArray objectAtIndex:ii]];
            NSString *bundleObjectName = [bundleDict valueForKey:@"Name"];
            NSString *documentsObjectName = [documentDict valueForKey:@"Name"];
            NSRange range = [documentsObjectName rangeOfString:bundleObjectName options:NSCaseInsensitiveSearch];
            if (range.location != NSNotFound) {
                 NSString *districtString = [bundleDict objectForKey:@"District"];
                if ([documentDict objectForKey:@"District"] != districtString) {
                    [documentDict setObject:districtString forKey:@"District"];
                    [documentArray replaceObjectAtIndex:ii withObject:documentDict];
                    updateDictionary=YES;
                }
            }
        }
    }
    if(updateDictionary){
        [documentArray writeToFile:path atomically:YES];
    }
}
}