2012-09-16 33 views
-1

如果Plist不存在,Plist将被复制到documents directory用字典纠正plist

如果它已存在,我想使用NSDictionary中的“名称”键bundleArraydocumentsArray中查找匹配的NSDictionary

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

如果找不到匹配项,则表示该词典必须添加到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

推测documentDict实际上是不可变的。即使您将其分配给NSMutableDictionary,这也不能准确描述底层数据。

NSMutableDictionary *documentDict = [documentArray objectAtIndex:ii]; 

应该是:

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

何地,你编辑documentDict,添加:

[documentArray replaceObjectAtIndex:ii withObject:documentDict]; 
+1

这不会更新属性列表,因为字典在可变时被复制 - OP需要我的解决方案。 – 2012-09-16 21:15:22

+1

编辑应该解决这个问题,而不必求助将CoreFoundation与NextStep混合。 –

+0

谢谢,一个非常简单的解决方案,完美地完成了这项工作 – ingenspor

0

当你从文件中读取一个plist中,一个不变的词典/阵列万古不易的孩子已创建,因此您的

  NSMutableDictionary *documentDict = [documentArray objectAtIndex:ii]; 

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

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