I have a plist of values ββthat I want to read in Core Data. I can read the "top level", but along with lines and numbers, each element also contains dictionaries. I'm having trouble getting the syntax right to read them.
Garden and plant are my 2 main data objects. Garden and plant are NSDictionaries containing data about themselves. Gardens can contain many plants, and specific plants can be in many gardens, so there are many different relationships.
This works a lot:
I use the plist gardens dictionary to populate my base database on firstRun, called from a completed application launch as follows:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; if (![defaults objectForKey:@"firstRun"]) { [defaults setObject:[NSDate date] forKey:@"firstRun"]; [[NSUserDefaults standardUserDefaults] synchronize]; [self loadGardenDataFromPlistDictionary]; }
It works. As well as the first level of loading various plist values ββinto the master data. But I am having problems loading the data contained in the "factories" dictionary, which is located in the "garden" dictionary ... 2 levels deep. In other words, the name, detail and notes are loaded ... but the plants do not. Here is my code:
-(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 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. }];
}
What am I missing?
source share