Search code examples
objective-crestkit

RestKit Identical To-One Mappings on Separate Objects Excepts


I know what I'm doing is quite simple, and I'm a bit confused as to what I'm doing wrong here.

I'm trying to have a given key on a JSON object always map to the same Objective-C class. This key has the same name on all of the JSON object's that have it (device).

I have two classes, Foo and Bar that each have a device property:

@interface Foo
@property (strong, nonatomic) Device * device;
@end

@interface Bar
@property (strong, nonatomic) Device * device;
@end

@interface Device
@property (strong, nonatomic) NSString * deviceId;
@property (strong, nonatomic) NSString * deviceName;
@end

And for the JSON that's sent by my server for Foo and Bar, the device is represented like so:

{
    "device": {
        "deviceId": "someId",
        "deviceName": "someName"
    }
}

In a configuration function for RestKit in my application, I have the following:

RKObjectMapping * responseMapping = [RKObjectMapping mappingForClass: model[@"class"]];

if ( model[@"class"] == [Foo class] ||
     model[@"class"] == [Bar class] ){

    NSArray * defaultRequestKeys = @[@"id", @"createdAt", @"updatedAt"];
    NSArray * defaultModelKeys = @[@"objectId", @"createdAt", @"updatedAt"];
    NSArray * deviceRequestKeys = [@[@"deviceName", @"deviceId"] arrayByAddingObjectsFromArray: defaultRequestKeys];
    NSArray * deviceModelKeys = [@[@"deviceName", @"deviceId"] arrayByAddingObjectsFromArray: defaultModelKeys];

    RKObjectMapping * deviceResponseMapping;

    deviceResponseMapping = [RKObjectMapping mappingForClass: [Device class]];
    [deviceResponseMapping addAttributeMappingsFromDictionary: [NSDictionary dictionaryWithObjects: deviceModelKeys
                                                                                           forKeys: deviceRequestKeys]];

    [responseMapping addRelationshipMappingWithSourceKeyPath:@"device" mapping: deviceResponseMapping];

}

However, RestKit excepts with failed: caught "NSInternalInconsistencyException", "Unable to add mapping for keyPath device, one already exists..."

Which means I'm doing something wrong.

I've tried looking all through the docs and I'm confused how I have the same key on two different objects use the same object mapping. This is for the Device to-one relationship on Foo and Bar.


Solution

  • In my case, I had declared this key already outside of the call to

    [responseMapping addRelationshipMappingWithSourceKeyPath:@"device" mapping: deviceResponseMapping];
    

    In another part of the code. Removing this key fixed the problem. I was adding it with:

    [responseMapping addAttributeMappingsFromDictionary: responseAttributeMappings];