7

我正在构建一个双向保管箱同步应用程序。我从核心数据加载对象,将它们转换为 JSON 并将它们发送到保管箱。但是,当我进行同步时,我会将一组本地 JSON 文件与保管箱 JSON 文件进行比较。如果检测到冲突,则应用同步逻辑。由于同步逻辑,可能会下载远程 JSON 文件并将替换本地 JSON 文件。

所以我最终在本地文档目录中得到了一堆 JSON 文件。

如何使用 RestKit 使用我定义的映射将本地 JSON 文件反序列化回对象?RKTwitterCoreData 从基于 Web 的 JSON 创建核心数据实体。我正在尝试对本地 JSON 文件执行相同的操作。

有一堆 loadObjects 方法,但它们似乎都适用于 Web 调用:

- (RKObjectLoader*)loadObjectsAtResourcePath:(NSString*)resourcePath delegate:(id<RKObjectLoaderDelegate>)delegate;

谢谢 !

4

3 回答 3

6

这是来自 Rest-Kit 文档,还没有尝试过,但看起来像是开始,因为他们使用 JSON 字符串。

你可以在这里找到它: 查看页面底部

NSString* JSONString = @"{ \"name\": \"The name\", \"number\": 12345}";
NSString* MIMEType = @"application/json";
NSError* error = nil;
id<RKParser> parser = [[RKParserRegistry sharedRegistry] parserForMIMEType:MIMEType];
id parsedData = [parser objectFromString:JSONString error:&error];
if (parsedData == nil && error) {
    // Parser error...
}


RKObjectMappingProvider* mappingProvider = [RKObjectManager sharedManager].mappingProvider;
RKObjectMapper* mapper = [RKObjectMapper mapperWithObject:parsedData mappingProvider:mappingProvider];
RKObjectMappingResult* result = [mapper performMapping];
if (result) {
    // Yay! Mapping finished successfully
}

编辑 请参阅关于保存上下文的 rob5408 注释:

 [[RKObjectManager sharedManager].objectStore.managedObjectContext save:&error];
于 2012-05-21T14:12:21.343 回答
1

如果你想拥有与“默认”Restkit 函数完全相同的行为,- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects 你可以使用它来获取宝贵的objectsNSArray :

RKObjectMappingResult* result = [mapper performMapping];
NSArray* objects = [result asCollection];
于 2012-10-03T15:54:36.083 回答
0

这是我用于核心数据到 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]];


}
于 2012-05-21T13:00:18.630 回答