2012-04-24 1 views
7

Tôi đang tạo ứng dụng đồng bộ hóa dropbox hai chiều. Tôi tải các đối tượng từ dữ liệu cốt lõi, chuyển đổi chúng thành JSON và gửi chúng tới dropbox. Tuy nhiên, khi tôi đồng bộ, tôi so sánh một tập hợp các tệp JSON cục bộ với các tệp JSON dropbox. Nếu một xung đột được phát hiện, một logic đồng bộ sẽ được áp dụng. Là kết quả của logic đồng bộ, một tệp JSON từ xa có thể được tải xuống và sẽ thay thế tệp JSON cục bộ.iPhone RestKit cách tải một tệp JSON cục bộ và ánh xạ nó tới một thực thể dữ liệu cốt lõi?

Vì vậy, tôi kết thúc với một loạt tệp JSON trong thư mục tài liệu cục bộ.

Làm cách nào để sử dụng RestKit để deserialize các tệp JSON cục bộ trở lại thành các đối tượng bằng ánh xạ mà tôi đã xác định? RKTwitterCoreData tạo một thực thể dữ liệu cốt lõi từ JSON dựa trên web. Tôi đang cố gắng làm như vậy với một tệp JSON cục bộ.

Có một loạt các phương pháp loadObjects, nhưng tất cả đều xuất hiện để làm việc với các cuộc gọi web:

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

Cảm ơn bạn!

+0

Bạn đã cố chuyển một đường dẫn cục bộ đến phương thức loadObjectsAtResourcePath chưa? – shannoga

Trả lời

0

Đây là những gì tôi đang sử dụng cho Dữ liệu cốt lõi để chuyển đổi dữ liệu từ JSON sang Core.

-(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); 
    } 

} 

Dưới đây là cách xác định mô hình đối tượng RestKit lồng nhau. Khi một tệp JSON của cấu trúc này đang được deserialized, nó sẽ tự động tạo ra tất cả các mối quan hệ lồng nhau cho bạn, và thậm chí hợp nhất bối cảnh đối tượng được quản lý!

+(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]]; 


} 
6

Đây là từ tài liệu Rest-Kit, Chưa thử nhưng có vẻ như bắt đầu khi họ sử dụng chuỗi JSON.

Bạn có thể tìm thấy nó ở đây: look at the bottom of the page

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 
} 

EDIT thấy nốt rob5408 về tiết kiệm bối cảnh:

[[RKObjectManager sharedManager].objectStore.managedObjectContext save:&error]; 
+0

Làm việc tuyệt vời. Cảm ơn! – jcanfield55

+1

Cảm ơn @shannoga, điều này cực kỳ hữu ích. Tôi muốn lưu ý rằng tôi đã phải lưu bối cảnh dữ liệu cốt lõi sau đó để có được các đối tượng để tồn tại. [[RKObjectManager sharedManager] .objectStore.managedObjectContext save: & error]; – rob5408

+0

Tuyệt vời, cảm ơn @ rob5408 cho ghi chú của bạn đã thêm nó vào câu trả lời – shannoga

1

Nếu bạn muốn có hành vi chính xác giống như " mặc định "Chức năng Restkit - (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects bạn có thể sử dụng chức năng này để nhận được số objects NSArray quý giá:

RKObjectMappingResult* result = [mapper performMapping]; 
NSArray* objects = [result asCollection];