title: Reading a plist into core data - NSDictionary within NSDictionary
body: <p>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.</p>
  
  <p>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.</p>
  
  <p>This much works:</p>
  
  <p>I use a plist dictionary of gardens to populate my core database on firstRun, called from application finised launching like so:</p>
  
  <pre><code>    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];  
      if (![defaults objectForKey:@"firstRun"])
      {
          [defaults setObject:[NSDate date] forKey:@"firstRun"];
          [[NSUserDefaults standardUserDefaults] synchronize];
          [self loadGardenDataFromPlistDictionary]; 
      }
  </code></pre>
  
  <p>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:</p>
  
  <pre><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:&amp;format errorDescription:&amp;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.
   }];   
  </code></pre>
  
  <p>}</p>
  
  <p>What am I missing?</p>