这是我用于核心数据到 JSON 到核心数据转换的内容。
-(void)deserializeFileAtPath:(NSString*)filePath
{
DLog(@"Deserialize file: %@",filePath);
NSError* error = nil;
NSString *stringJSON = [NSString stringWithContentsOfFile:filePath usedEncoding:nil error:&error];
if(error)
{
NSLog(@"Error reading from file: %@", filePath);
}
//restore the dictionary, as it was serialized
NSDictionary* serializationDictionary = [NSJSONSerialization JSONObjectWithData:[NSData dataWithContentsOfFile:filePath] options:NSJSONReadingMutableContainers error:&error];
//Here you must ensure that your object mapping exists
[CoreDataWrapper setupCoreDataObjectMapping];
//top level object within JSON it will have one entity that you really want to deserialize. Without a wrapper, the mapper would not know what the top level entity really is
CoreDataWrapper* wrapper = [CoreDataWrapper object];
RKObjectMapper* mapper;
error = nil;
//this performs deserialization. if you get errors about designated initializer not being called, you have setup a wrong object mapping. You need to define RKManagedObjectMapping for your core data classes
mapper = [RKObjectMapper mapperWithObject:serializationDictionary
mappingProvider:[RKObjectManager sharedManager].mappingProvider];
RKObjectMappingResult* result = [mapper performMapping];
//top level object within wrapper that holds the real payload
RealCoreDataEntity* realCoreData = [result asObject];
realCoreData.wrapper = wrapper;
//just in case
[[wrapper managedObjectContext]save:nil];
//prints what we got back
DLog(@"%@", realCoreData);
//prints any nested relationships
for(NestedRelationshipObject* relationshipEntity in realCoreData.relationship)
{
DLog(@"Nested entity:%@", relationshipEntity);
}
}
下面介绍如何定义嵌套的 RestKit 对象模型。当这个结构的 JSON 文件被反序列化时,它会自动为你创建所有的嵌套关系,甚至合并托管对象上下文!
+(void)setupCoreDataObjectMapping
{
RKObjectManager *objectManager = [RKObjectManager sharedManager ] ;
// Setup our object mappings
/*!
Mapping by entity. Here we are configuring a mapping by targetting a Core Data entity with a specific
name. This allows us to map back Twitter user objects directly onto NSManagedObject instances --
there is no backing model class!
*/
//********************************
RKManagedObjectMapping* nestedRelationshipMapping = [RKManagedObjectMapping mappingForEntityWithName:@"NestedRelationshipObject"];
//UUID determines which objects get updated and which ones get created during the mapping process
nestedRelationshipMapping.primaryKeyAttribute = @"uuid";
[nestedRelationshipMapping mapKeyPathsToAttributes:
@"IKeepTheseTheSame", @"IKeepTheseTheSame",
@"AnotherValue",@"AnotherValue",
//keep adding your attributes
nil];
[objectManager.mappingProvider addObjectMapping:nestedRelationshipMapping];
//********************************
RKManagedObjectMapping* mainPayloadMapping = [RKManagedObjectMapping mappingForEntityWithName:@"RealCoreDataEntity"];
mainPayloadMapping.primaryKeyAttribute = @"uuid";
[mainPayloadMapping mapKeyPathsToAttributes:
@"companyName",@"companyName",
//keep adding your attributes
nil];
//this is the main payload. I create all of it's relationships before, and then add them to the mapping.
[mainPayloadMapping mapRelationship:@"relationshipName" withMapping:nestedRelationshipMapping];
[objectManager.mappingProvider addObjectMapping:mainPayloadMapping];
[objectManager.mappingProvider setSerializationMapping:[mainPayloadMapping inverseMapping] forClass:[YourNSManagedObjectSubclass class]];
[objectManager.mappingProvider setMapping:nestedRelationshipMapping forKeyPath:@"mainPayloadToNestedDataRelationshipName"];
[objectManager.mappingProvider setMapping:mainPayloadMapping forKeyPath:@"wrapperToMainPayloadRelationshipName"];
//this is a top level JSON object. It's name will not be identified within the object, but it's relationshipName will be. The result of deserializing this object would be an object that is being wrapped.
RKManagedObjectMapping* wrapperMapping = [RKManagedObjectMapping mappingForClass:[IconFileWrapper class]];
iconWrapperMapping.primaryKeyAttribute = @"uuid";
// keyPath and attribute names. must be even
[iconWrapperMapping mapKeyPathsToAttributes:@"uuid",@"uuid",nil];
//keep adding your attributes
[iconWrapperMapping mapRelationship:@"relationshipName" withMapping:mainPayloadMapping];
[objectManager.mappingProvider addObjectMapping:wrapperMapping];
[objectManager.mappingProvider setSerializationMapping:[wrapperMapping inverseMapping] forClass:[YourWrapperNSManagedObjectSubclass class]];
}