2011-07-18 9 views
4

コアデータを読みたい値があります。私は "トップレベル"で読むことができますが、文字列や数字とともに、各項目には辞書も含まれています。私はそれらを読むために文法上の権利を得ることに問題があります。コアデータへのplistの読み込み - NSDictionary内のNSDictionary

ガーデニングとプラントは私の2つのコアデータエンティティです。ガーデンとプラントの両方は、自分自身に関するデータを含んでいるNS辞書です。庭には多くの植物が含まれており、特定の植物は多くの庭園に収めることができるため、多対多の関係があります。

これくらいの作品:

私はfirstRunの私のコアデータベースを作成する庭園のplistの辞書を使用して、アプリケーションから呼び出さはそうのような起動finised:

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

}

私は何をしないのですか?

答えて

2

Plant辞書値ごとに新しい管理対象オブジェクトを作成しているわけではありません。あなたは、もちろん、それが動作しない関係に辞書自体を割り当てようとしています。それが必要なPlantオブジェクトを作成し、正しいGardenオブジェクトとの関係を設定します...

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

はあなたのような何かを追加する必要があります。

+0

特定の正しいコードについては、TechZenに感謝いたします。それは本当にそれを見るのを助けた。それはうまくいって、私をつかまえませんでした! –

関連する問題