I'm using RestKit for a project and i noticed that there is no longer a method in the class that you can control all mappings in (elementToPropertyMappings), i therefore wondered where the best place to put the new code was, currently i'm doing it in my view controller, but i'll be using most of the same mappings in other areas of my code so is there a more efficient place to put it:
The code i am referring to is:
RKO开发者_运维知识库bjectMapping* userMapping = [RKObjectMapping mappingForClass:[User class]];
[userMapping mapKeyPath:@"id" toAttribute:@"identifier"];
[userMapping mapKeyPath:@"forename" toAttribute:@"forename"];
[userMapping mapKeyPath:@"surname" toAttribute:@"surname"];
[userMapping mapKeyPath:@"email" toAttribute:@"email"];
[userMapping mapKeyPath:@"twitter_username" toAttribute:@"twitterUsername"];
[userMapping mapKeyPath:@"created" toAttribute:@"created"];
[userMapping mapKeyPath:@"use_gravatar" toAttribute:@"useGravatar"];
[userMapping mapKeyPath:@"avatar_url" toAttribute:@"avatarURL"];
[userMapping mapKeyPath:@"gender" toAttribute:@"gender"];
[[RKObjectManager sharedManager].mappingProvider setMapping:userMapping forKeyPath:@"user"];
It would be great if this could be in a method on the User class that i can then call to setup these mappings etc.
Many Thanks
There are a few good ways to organize your mappings currently recommended:
- Put all of your mappings into your app delegate and configure them at app initialization. This keeps them out of the controllers and is useful if you have a small number of mappings.
- Subclass the RKObjectMappingProvider and build all of your mappings in the init method of your subclass, then instantiate and assign your mapping provider instance to the object manager.
- Add a category to RKObjectMappingProvider with a method like 'defineMappings'. Then import the header into your app delegate and invoke it via [mappingProvider defineMappings] after you initialize RestKit.
The problem with defining mappings on a class method is that when you have relationships, you can wind up with circular dependencies as there's no ivars available to store the instances. We may be able to do something with blocks to help alleviate this problem, but no such work has been done yet.
I think the domain model should be the only one who should know about the mapping. Here is how I map some flickr json:
I call the mappings when you need them (Can be in AppDelegate or where ever you want)
// Setup our object mappings
RKObjectMapping *photoMapping = [Photo mapWithMapping:nil];
RKObjectMapping *photosMapping = [Photos mapWithMapping:photoMapping];
And this is one of my domain objects: It contains the classMethod doing the mapping.
#import "Photos.h"
@implementation Photos
+ (RKObjectMapping*)mapWithMapping: (RKObjectMapping*)aMapping
{
RKObjectManager *objectManager = [RKObjectManager sharedManager];
RKManagedObjectMapping *mapping = [RKManagedObjectMapping mappingForClass:[self class] inManagedObjectStore:objectManager.objectStore];
[mapping mapKeyPathsToAttributes:
@"page", @"page",
@"pages", @"pages",
@"perpage", @"perpage",
@"stat", @"stat",
@"total", @"total",
nil];
if (aMapping) {
[mapping mapRelationship:@"photo" withMapping:aMapping];
}
return mapping;
}
@end
I typically create a private method in my App Delegate that I call during app setup which sets up the RKObjectManager and then constructs all the mappings I use throughout the app. I believe the RestKit sample projects use this same pattern, so definitely check those out as a reference.
精彩评论