IPhone RestKit, how to download a local JSON file and map it to the main data object?

I am creating a two-way app to sync with Dropbox. I load objects from the master data, convert them to JSON and send them to Dropbox. However, when I synchronize, I compare a set of local JSON files with JSON files from Dropbox. If a conflict is detected, the synchronization logic is applied. As a result of the synchronization logic, you can load the remote JSON file and replace the local JSON file.

So, I get a bunch of JSON files in the local document directory.

How to use RestKit to deserialize local JSON files back to objects using the mappings I defined? RKTwitterCoreData creates the main data object from web JSON. I am trying to do the same with a local JSON file.

There are many loadObjects methods, but they all work with web calls:

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

Thanks!

+7
source share
3 answers

This is from the Rest-Kit docs, haven't tried it yet, but it looks like a start, since they use a JSON string.

You can find it here: 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 see rob5408 saving context note:

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

If you want to have the same behavior as the default "Restkit" function "t20> you can use this to get valuable NSArray objects :

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

Here is what I use to convert Core Data to JSON in Core Data.

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

Here's how to define a RestKit nested object model. When the JSON file of this structure is deserialized, it will automatically create all the nested relationships for you and even combine the contexts of managed objects!

 +(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 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 name will not be identified within the object, but it 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]]; } 
0
source

All Articles