Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where's the best place to put object mappings in RestKit

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:

RKObjectMapping* 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

like image 241
Matthew Lanham Avatar asked Aug 25 '11 12:08

Matthew Lanham


2 Answers

There are a few good ways to organize your mappings currently recommended:

  1. 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.
  2. 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.
  3. 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.

like image 177
Blake Watters Avatar answered Oct 22 '22 05:10

Blake Watters


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
like image 37
Tycho Pandelaar Avatar answered Oct 22 '22 06:10

Tycho Pandelaar