如何打印出Core Data对象?
问题描述:
我想打印出存储在NSLog语句代码中的Core Data对象中的数据。如何打印出Core Data对象?
背景信息:我正在从PList中读取预填充数据,然后将其转换为Core Data。发布的应用程序只能从核心数据读取。
这里是我的plist是什么样子:
这里是我的对象图:
这里是我的代码:
-(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
您如何使这项工作适用于关系?
答
最简单的方法是
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
谢谢为您的答案,我感谢您提出的重命名约定。 – 2014-09-08 18:25:49
这似乎是一个干净的方式来做到这一点。然而,我的完整对象图中有很多实体类(总共32个,这只是一个示例部分),并且为每个类手动创建一个漂亮的描述需要很多工作。此外,无论何时我对对象图进行更改并自动生成实体类,我都必须再次添加代码。有没有办法在NSManagedObject中创建一个继承的prettyDescription,并打印任何类型的实体的所有属性? – 2014-09-08 18:32:52
我认为有可能把它抽象出来,但当然也不是没有努力。一个实用的选择是使用'description'并且手动添加关系的'描述'。 – Mundi 2014-09-08 21:31:58