2
votes

I'm trying to map json to core data objects with RestKit 0.20 in my iOS application. I have two types of objects: Users and Messages. User has many messages. Message has fields: 'from' and 'to' which point to User. Here's my Messages json:

[
    {
        "created_at":1358265482867,
        "to":"50ed7b4e63e9b80200000009",
        "note":"Hello",
        "from":"50ee98365315d00200000003",
        "_id":"50f57cee11f2b00200000016",
        "__v":0
    },
    {
        "created_at":1358265582867,
        "to":"50ed7b4e63e9b80200000009",
        "note":"Hello 2",
        "from":"50ee98365315d00200000003",
        "_id":"50f57cee11f2b00200000016",
        "__v":0
    }
]

My mapping code looks like:

// Object mappings
RKEntityMapping *userMapping = [RKEntityMapping mappingForEntityForName:@"User" inManagedObjectStore:managedObjectStore];
userMapping.identificationAttributes = @[@"userId"];
[userMapping addAttributeMappingsFromDictionary:@{
     @"_id": @"userId",
     @"name": @"name",
     @"note": @"headline",
     @"photo_url": @"photoUrl"
 }];

RKEntityMapping *messageMapping = [RKEntityMapping mappingForEntityForName:@"Message" inManagedObjectStore:managedObjectStore];
messageMapping.identificationAttributes = @[@"messageId"];
[messageMapping addAttributeMappingsFromDictionary:@{
     @"_id": @"messageId",
     @"note": @"note",
     @"created_at": @"createdAt",
     @"from": @"from",
     @"to" : @"to"
 }];

// !!! This code is ok if json contains entire object (but contains only id).
// [messageMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"from" toKeyPath:@"from" withMapping:userMapping]];
// [messageMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"to" toKeyPath:@"to" withMapping:userMapping]];

RKEntityMapping *messageReversedMapping = [messageMapping inverseMapping];
RKRequestDescriptor *requestDescription = [RKRequestDescriptor requestDescriptorWithMapping:messageReversedMapping objectClass:[Message class] rootKeyPath:nil];
[objectManager addRequestDescriptor:requestDescription];

RKResponseDescriptor *userResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:userMapping pathPattern:@"/users" keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[objectManager addResponseDescriptor:userResponseDescriptor];

RKResponseDescriptor *messageResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:messageMapping pathPattern:@"/messages" keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[objectManager addResponseDescriptor:messageResponseDescriptor];

Models code:

@interface Message : NSManagedObject

@property (nonatomic, retain) NSString * note;
@property (nonatomic, retain) NSNumber * createdAt;
@property (nonatomic, retain) NSString * messageId;
@property (nonatomic, retain) User *from;
@property (nonatomic, retain) User *to;


@interface User : NSManagedObject

@property (nonatomic, retain) NSString * email;
@property (nonatomic, retain) NSString * headline;
@property (nonatomic, retain) NSString * lastName;
@property (nonatomic, retain) NSNumber * me;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSString * photoUrl;
@property (nonatomic, retain) NSString * userId;
@property (nonatomic, retain) Message *messagesFrom;
@property (nonatomic, retain) Message *messagesTo;

The problem is that in json, fields "to" and "from" are user's ids instead of the nested objects, so application crashes.

I've found similar SO questions but still can't make it work.

Mapping nested IDs with RestKit in Xcode using Objective-C

Mapping relationships in RestKit through an array of IDs doesn't work

Could anyone help me with setup mapping correctly, so json would contain only users' ids and not nested objects?

1

1 Answers

1
votes

OK I figured it out. API documentation gives an example how to map this kind of relation: http://restkit.org/api/latest/Classes/RKConnectionDescription.html

I still need to map fields 'from' and 'to' to dummy 'fromUserId' and 'toUserId' but it works.

This code works for me:

NSManagedObjectContext *context = ApplicationDelegate.managedObjectContext;
NSEntityDescription *messageEntity = [NSEntityDescription entityForName:@"Message" inManagedObjectContext:context];
NSRelationshipDescription *userRelationshipFrom = [messageEntity relationshipsByName][@"from"];
RKConnectionDescription *connectionUserMessageFrom = [[RKConnectionDescription alloc] initWithRelationship:userRelationshipFrom attributes:@{ @"fromUserId": @"userId" }];
[messageMapping addConnection:connectionUserMessageFrom];

NSRelationshipDescription *userRelationshipTo = [messageEntity relationshipsByName][@"to"];
RKConnectionDescription *connectionUserMessageTo = [[RKConnectionDescription alloc] initWithRelationship:userRelationshipTo attributes:@{ @"toUserId": @"userId" }];
[messageMapping addConnection:connectionUserMessageTo];