将一个plist读入核心数据 - NSDictionary中的NSDictionary [英] Reading a plist into core data - NSDictionary within NSDictionary

查看:247
本文介绍了将一个plist读入核心数据 - NSDictionary中的NSDictionary的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一组值要读入核心数据。我可以读顶级,但与字符串和数字,每个项目也包含字典。我无法获取读取这些语法的语法。

I have a plist of values I want to read into Core Data. I can read in the "top level," but along with strings and numbers, each item also contains dictionaries. I am having trouble getting the syntax right to read those.

花园和植物是我的2核心数据实体。花园和植物是包含关于自己的数据的NSDictionaries。花园可以容纳许多植物,具体植物可以在许多花园中,所以有许多关系。

Garden and Plant are my 2 Core Data Entities. Both Garden and Plant are NSDictionaries containing data about themselves. Gardens can contain many plants, and specific plants can be in many gardens, so there is a many to many relationship.

这很有效:

我使用花园的plist字典填充我的核心数据库在firstRun,从应用程序finiated启动如下:

I use a plist dictionary of gardens to populate my core database on firstRun, called from application finised launching like so:

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];  
    if (![defaults objectForKey:@"firstRun"])
    {
        [defaults setObject:[NSDate date] forKey:@"firstRun"];
        [[NSUserDefaults standardUserDefaults] synchronize];
        [self loadGardenDataFromPlistDictionary]; 
    }

将各种plist值加载到核心数据的第一级也是如此。但我有麻烦加载数据,包含在植物字典内的花园字典... 2级深。换句话说,名称,细节和注释加载...但植物不。这里是我的代码到目前为止:

That works. And so does the first level of loading the various plist values into core data. But I am having trouble loading data that is contained within the "plants" dictionary that is inside the "garden" dictionary... 2 levels deep. In other words, name, detail, and notes load... but plants do not. Here's my code so far:

 -(void) loadGardenDataFromPlistDictionary{
// build path to plist; check Documents first, then Bundle.
NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
NSString *plistPath = [documentsPath stringByAppendingPathComponent:@"defaultGardenDictionary.plist"];
if (![[NSFileManager defaultManager] fileExistsAtPath:plistPath]) 
{
    // if not in documents, get property list from main bundle
    plistPath = [[NSBundle mainBundle] pathForResource:@"defaultGardenDictionary" ofType:@"plist"];
}

// read property list into memory as an NSData object
NSData *plistXML = [[NSFileManager defaultManager] contentsAtPath:plistPath];
NSString *errorDesc = nil;
NSPropertyListFormat format;

// convert static property list into dictionary object
NSDictionary *plistDictionary = (NSDictionary *)[NSPropertyListSerialization propertyListFromData:plistXML mutabilityOption:NSPropertyListMutableContainersAndLeaves format:&format errorDescription:&errorDesc];
if (!plistDictionary) 
{
    NSLog(@"Error reading plist: %@, format: %d", errorDesc, format);
}


NSManagedObjectContext *context = self.managedObjectContext;

[plistDictionary enumerateKeysAndObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(id key, id object, BOOL *stop) {
    NSManagedObject *gardenManObj = [NSEntityDescription insertNewObjectForEntityForName:@"Garden" inManagedObjectContext:context];

    [gardenManObj setValue:[thisGardenDictionary objectForKey:@"name"] forKey:@"name"];
    [gardenManObj setValue:[thisGardenDictionary objectForKey:@"detail"] forKey:@"detail"];
    [gardenManObj setValue:[thisGardenDictionary objectForKey:@"notes"] forKey:@"notes"];
    [gardenManObj setValue:[thisGardenDictionary objectForKey:@"rating"] forKey:@"rating"];

    NSDictionary *thisGardenPlantsDictionary = [thisGardenDictionary objectForKey:@"plants"];
    NSLog(@"thisGardenPlantsDictionary contains %i dictionaries.", [thisGardenPlantsDictionary count]);
    //The trace statement above shows the correct number of plants in each garden dictionary. oooh... so tantalizingly close!

    //However, the next item is the dictionary of plants in this garden. It comes up blank. 
    //I don't understand the syntax to load that dictionary of plants into its corresponding dictionary of plants within a garden in core data. 

    //I deleted most of the things I've tried and failed with so far. Here's my last attempt:

    // the obvious and parallel:
    [gardenManObj setValue:[thisGardenDictionary objectForKey:@"plants"] forKey:@"plants"];
        //did not work; xCode compiler objected to "incompatible pointer types."

    //the compiler seemed to want an NSSet, so I tried:
    NSSet *thisGardenPlantsSet = [thisGardenDictionary mutableSetValueForKey:@"steps"];
        NSLog(@"thisGardenPlantsSet contains %i sets.", [thisGardenPlantsSet count]);
    [gardenManObj setValue:thisGardenPlantsSet forKey:@"steps"];
    //the compiler was fooled, but the setValue crashed at runtime.
 }];   

}

推荐答案

您不是为每个植物字典创建一个新的托管对象值。你只是试图分配字典本身的关系,当然不会工作。

You are not creating a new managed object for each Plant dictionary value. You are just trying to assign the dictionary itself to the relationship which, of course, will not work.

您需要添加以下内容:

[gardenManObj setValue:[thisGardenDictionary objectForKey:@"rating"] forKey:@"rating"];

NSDictionary *thisGardenPlantsDictionary = [thisGardenDictionary objectForKey:@"plants"];
NSLog(@"thisGardenPlantsDictionary contains %i dictionaries.", [thisGardenPlantsDictionary count]);
NSManagedObject *plantMO;
for (Plant *eachPlant in thisGardenPlantsDictionary) {
  plantMO=[NSEntityDescription insertNewObjectForEntityForName:@"Plant" inManagedObjectContext:context];
  [plantMO setValue:[eachPlant valueForKey:@"someValue" forKey:@"someKey"]];
   //... repeat for all attributes
  [plantMO setValue:gardenManObj forKey:@"gardent"];
}

...将创建必要的 / code>对象,并使用正确的 Garden 对象设置关系。

... that will create the necessary Plant objects and set the relationship with the correct Garden object.

这篇关于将一个plist读入核心数据 - NSDictionary中的NSDictionary的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆