2014-09-05 112 views
1

我想打印出存儲在NSLog語句代碼中的Core Data對象中的數據。如何打印出Core Data對象?

背景信息:我正在從PList中讀取預填充數據,然後將其轉換爲Core Data。發佈的應用程序只能從核心數據讀取。

這裏是我的plist是什麼樣子:

Recipes.plist

這裏是我的對象圖:

object graph

這裏是我的代碼:

-(void)initXML 
{ 
    [self deleteAllEntities:@"Recipes"]; 

    [self copyXMLtoEntities]; 

    [self printEntities]; 
} 

_

// deletes data from all entities to ready them for pre-population 
-(void)deleteAllEntities:(NSString *)entityDescription 
{ 
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
    NSEntityDescription *entity = [NSEntityDescription entityForName:entityDescription inManagedObjectContext:self.managedObjectContext]; 
    [fetchRequest setEntity:entity]; 

    NSError *error; 
    NSArray *items = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error]; 

    for (NSManagedObject *managedObject in items) 
    { 
     [self.managedObjectContext deleteObject:managedObject]; 
     DLog(@"%@ ..object deleted", entityDescription); 
    } 

    if (![self.managedObjectContext save:&error]) 
    { 
     DLog(@"Error deleting %@ - error:%@", entityDescription, error); 
    } 
} 

_

// This copies data from the PList to Core Data Entities, aka pre-population 
-(void)copyXMLtoEntities 
{   
    NSDictionary *allRecipesDictionary = [self getRecipes]; 
    DLog(@"allRecipes: [%@]", allRecipesDictionary); 

    Recipes *recpies = [NSEntityDescription insertNewObjectForEntityForName:@"Recipes" inManagedObjectContext:self.managedObjectContext]; 

    for (NSString *recipeKey in allRecipesDictionary) 
    { 
     NSDictionary *recipeDict = [allRecipesDictionary objectForKey:recipeKey]; 

     Recipe *recipe = [NSEntityDescription insertNewObjectForEntityForName:@"Recipe" inManagedObjectContext:self.managedObjectContext]; 
     recipe.id = recipeKey; 
     recipe.name = [recipeDict objectForKey:@"name"]; 

     NSMutableArray *contentItemsArray = [[NSMutableArray alloc] init];    

     NSArray *contentArrayToIterate = [recipeDict objectForKey:@"content"];    

     // loop through content array and add each item 
     for (int i=0 ; i < [contentArrayToIterate count] ; i++) 
     { 
      // create text or image content items 
      // add them to the array 
      // create entities and add them to contentItemsArray 

      NSDictionary *contentItemDict = contentArrayToIterate[i]; 

      NSDictionary *textItemDict = [contentItemDict objectForKey:@"textItem"]; 
      NSDictionary *imageItemDict = [contentItemDict objectForKey:@"imageItem"]; 
      NSString *sequenceStr = [contentItemDict objectForKey:@"sequence"]; 

      if (textItemDict != nil) 
      { 
       NSString *text = [textItemDict objectForKey:@"text"]; 
       TextItem *textItem = [NSEntityDescription insertNewObjectForEntityForName:@"TextItem" inManagedObjectContext:self.managedObjectContext]; 

       textItem.text = text; 
       textItem.sequence = sequenceStr; 

       // add entity to the array 
       [contentItemsArray addObject:textItem]; 
      } 

      if (imageItemDict != nil) 
      { 
       NSString *filename = [imageItemDict objectForKey:@"filename"]; 

       ImageItem *imageItem = [NSEntityDescription insertNewObjectForEntityForName:@"ImageItem" inManagedObjectContext:self.managedObjectContext]; 

       imageItem.filename = filename; 
       imageItem.sequence = sequenceStr; 

       // add entity to the array 
       [contentItemsArray addObject:imageItem]; 
      } 
     } // loop through content 

     recipe.contentItems = [NSSet setWithArray:contentItemsArray]; 
     [recpies addRecipeObject:recipe]; 
    } // loop through recipes 

    [self saveContext]; 
} 

_

// This returns the Dictionary of Recipes 
-(NSDictionary *)getRecipes 
{ 
    NSString *path = [[NSBundle mainBundle] pathForResource:@"Recipes" ofType:@"plist"]; 
    NSDictionary *plist = [[NSDictionary alloc] initWithContentsOfFile:path]; 

    // recipes 
    NSDictionary *recipes = [plist objectForKey:@"Recipes"]; 

    return recipes; 
} 

_

打印這樣的詞典:

DLog(@"allRecipes: [%@]", allRecipesDictionary); 

給了我很好的分類輸出是這樣的:

allRecipes: [{ 
    "BLUEBERRY_PIE_001" =  { 
     content =   (
          { 
           textItem =     { 
            sequence = 1; 
            text = "Mix sugar, cornstarch, salt, and cinnamon, and sprinkle over blueberries."; 
           }; 
          }, 
          { 
           imageItem =     { 
            filename = "mixIngredients.jpg"; 
            sequence = 2; 
           }; 
          }, 
           ... 

打印出核心數據實體的形式是這樣的:

DLog(@"self.recipes: [%@]", self.recipes); 

或本:

DLog(@"| self.recipes description: [%@]", [self.recipes description]); 

給了我這樣的:

self.recipes: [(
"<Recipes: 0x9951840> (entity: Recipes; id: 0x9962730 <x-coredata://4E308A08-FB8A-44C5-887A-88C335378A14/Recipes/p2> ; data: {\n recipe =  (\n );\n})" 

)]

我怎樣才能讓它看起來像字典打印輸出?我能想到的直接方法是爲每個遍歷自己集合的實體添加一個「打印」方法。我的完整應用程序中有32個實體。我想避免每次從對象圖生成新實體時都必須編寫此代碼。

更有效的方法是掃描每個實體的屬性並遍歷它們。此鏈接顯示如何爲屬性執行此操作,但不顯示關係: http://iphonedevelopment.blogspot.com/2010/08/core-data-odds-and-ends.html

您如何使這項工作適用於關係?

回答

1

最簡單的方法是

for (Recipe *r in recipesObject.recipe) { NSLog(@"%@", r); } 

你會得到一些額外的不那麼漂亮核心數據輸出,但如果是用於信息或調試,應該沒事。此外,關係可能不會完全記錄。

更好的是,創建一個像prettyDescription這樣的方法,根據您的喜好格式化輸出。你可以把它放到NSManagedObject子類中或者(更好)它的擴展。

-(NSString*)prettyDescription { 
    NSMutableString *result = [NSMutableString new]; 
    [result appendString:self.name]; 
    [result appendString:@"\n"]; 
    for (ContentItem *item in self.contentItems) { 
     // append details from item to the result 
    } 
    return [NSString stringWithString:result]; // return immutable string 
} 

現在,您可以記錄所有的食譜

for (Recipe *r in recipesObject.recipe) { NSLog(@"%@", r.prettyDescription); } 

注:我覺得你應該重命名實體和清晰度屬性如下:

Recipes   --> RecipesCollection 
Recipes.recipe --> RecipesCollection.recipes 
Recipe.recipes --> Recipe.collection 
+1

謝謝爲您的答案,我感謝您提出的重命名約定。 – 2014-09-08 18:25:49

+1

這似乎是一個乾淨的方式來做到這一點。然而,我的完整對象圖中有很多實體類(總共32個,這只是一個示例部分),並且爲每個類手動創建一個漂亮的描述需要很多工作。此外,無論何時我對對象圖進行更改並自動生成實體類,我都必須再次添加代碼。有沒有辦法在NSManagedObject中創建一個繼承的prettyDescription,並打印任何類型的實體的所有屬性? – 2014-09-08 18:32:52

+0

我認爲有可能把它抽象出來,但當然也不是沒有努力。一個實用的選擇是使用'description'並且手動添加關係的'描述'。 – Mundi 2014-09-08 21:31:58