我想要读入Core Data中有一些值。我可以在“顶级”中阅读,但除了字符串和数字外,每个项目还包含字典。我无法正确阅读这些语法。
Garden and Plant是我的2个核心数据实体。 Garden和Plant都是包含自己数据的NSDictionaries。花园可以包含许多植物,特定的植物可以在许多花园中,所以有很多种关系。
这很有效:
我使用plist的花园字典在firstRun上填充我的核心数据库,从应用程序启动调用就像这样:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if (![defaults objectForKey:@"firstRun"])
{
[defaults setObject:[NSDate date] forKey:@"firstRun"];
[[NSUserDefaults standardUserDefaults] synchronize];
[self loadGardenDataFromPlistDictionary];
}
有效。第一级将各种plist值加载到核心数据中也是如此。但是我无法加载“花园”字典中“植物”字典中包含的数据... 2级深度。换句话说,名称,细节和笔记加载...但植物没有。到目前为止,这是我的代码:
-(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.
}];
}
我错过了什么?
答案 0 :(得分:2)
您没有为每个Plant
字典值创建新的托管对象。您只是尝试将字典本身分配给关系,当然,这种关系不起作用。
您需要添加以下内容:
[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"];
}
...将创建必要的Plant
个对象,并设置与正确的Garden
对象的关系。