我有一个核心数据对象图(由通过多对多关系链接的两个实体组成)。
作为一个相对缺乏经验的iPhone开发人员,我很好奇,是否有人可以推荐一种方法以及适合iPhone的JSON实现,这将使我能够:
将核心数据记录转换为JSON字符串(以保持实体之间的关系);和
将JSON字符串转换回核心数据对象(再次保留实体之间的关系)。
在这一点上,我没有搜索到教程/代码示例,因此将不胜感激。
首先,选择一个要使用的JSON库,我个人喜欢TouchJSON,但那里的其他几个库也相当不错。尽管不是很困难,但复杂的部分是将托管对象转换为适合的结构以进行转换。我写这个真正的快,所以它可能有一个或两个错误:)
您调用的方法是:
- (NSString*)jsonStructureFromManagedObjects:(NSArray*)managedObjects; - (NSArray*)managedObjectsFromJSONStructure:(NSString*)json withManagedObjectContext:(NSManagedObjectContext*)moc;
并实现如下:
- (NSDictionary*)dataStructureFromManagedObject:(NSManagedObject*)managedObject { NSDictionary *attributesByName = [[managedObject entity] attributesByName]; NSDictionary *relationshipsByName = [[managedObject entity] relationshipsByName]; NSMutableDictionary *valuesDictionary = [[managedObject dictionaryWithValuesForKeys:[attributesByName allKeys]] mutableCopy]; [valuesDictionary setObject:[[managedObject entity] name] forKey:@"ManagedObjectName"]; for (NSString *relationshipName in [relationshipsByName allKeys]) { NSRelationshipDescription *description = [[[managedObject entity] relationshipsByName] objectForKey:relationshipName]; if (![description isToMany]) { NSManagedObject *relationshipObject = [managedObject valueForKey:relationshipName]; [valuesDictionary setObject:[self dataStructureForManagedObject:relationshipObject] forKey:relationshipName]; continue; } NSSet *relationshipObjects = [managedObject objectForKey:relationshipName]; NSMutableArray *relationshipArray = [[NSMutableArray alloc] init]; for (NSManagedObject *relationshipObject in relationshipObjects) { [relationshipArray addObject:[self dataStructureForManagedObject:relationshipObject]]; } [valuesDictionary setObject:relationshipArray forKey:relationshipName]; } return [valuesDictionary autorelease]; } - (NSArray*)dataStructuresFromManagedObjects:(NSArray*)managedObjects { NSMutableArray *dataArray = [[NSMutableArray alloc] init]; for (NSManagedObject *managedObject in managedObjects) { [dataArray addObject:[self dataStructureForManagedObject:managedObject]]; } return [dataArray autorelease]; } - (NSString*)jsonStructureFromManagedObjects:(NSArray*)managedObjects { NSArray *objectsArray = [self dataStructuresFromManagedObjects:managedObjects]; NSString *jsonString = [[CJSONSerializer serializer] serializeArray:objectsArray]; return jsonString; } - (NSManagedObject*)managedObjectFromStructure:(NSDictionary*)structureDictionary withManagedObjectContext:(NSManagedObjectContext*)moc { NSString *objectName = [structureDictionary objectForKey:@"ManagedObjectName"]; NSManagedObject *managedObject = [NSEntityDescription insertNewObjectForEntityForName:objectName inManagedObjectContext:moc]; [managedObject setValuesForKeysWithDictionary:structureDictionary]; for (NSString *relationshipName in [[[managedObject entity] relationshipsByName] allKeys]) { NSRelationshipDescription *description = [relationshipsByName objectForKey:relationshipName]; if (![description isToMany]) { NSDictionary *childStructureDictionary = [structureDictionary objectForKey:relationshipName]; NSManagedObject *childObject = [self managedObjectFromStructure:childStructureDictionary withManagedObjectContext:moc]; [managedObject setObject:childObject forKey:relationshipName]; continue; } NSMutableSet *relationshipSet = [managedObject mutableSetForKey:relationshipName]; NSArray *relationshipArray = [structureDictionary objectForKey:relationshipName]; for (NSDictionary *childStructureDictionary in relationshipArray) { NSManagedObject *childObject = [self managedObjectFromStructure:childStructureDictionary withManagedObjectContext:moc]; [relationshipSet addObject:childObject]; } } return managedObject; } - (NSArray*)managedObjectsFromJSONStructure:(NSString*)json withManagedObjectContext:(NSManagedObjectContext*)moc { NSError *error = nil; NSArray *structureArray = [[CJSONDeserializer deserializer] deserializeAsArray:json error:&error]; NSAssert2(error == nil, @"Failed to deserialize\n%@\n%@", [error localizedDescription], json); NSMutableArray *objectArray = [[NSMutableArray alloc] init]; for (NSDictionary *structureDictionary in structureArray) { [objectArray addObject:[self managedObjectFromStructure:structureDictionary withManagedObjectContext:moc]]; } return [objectArray autorelease]; }
现在这是递归的,因此如果不小心,您可以轻松地转换整个持久性存储。观察您的关系,并确保它们仅“向下”进入对象树,以便仅获得要转换的对象。