2014-09-05 114 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