Search code examples
ioscore-datarestkitentity-relationshiprestkit-0.20

RESTKit: Objects are losing relationships


JSON data received:

{
    "meeting": [{
        "meetingId": 506,
        "ownerId": "John.Doe",
        "startDate": "2014-07-27T13:15:07.000Z",
        "activities": [{
            "activityType": "Active Activity",
            "activityId": 729,
            "locationAddress": "1188 El Camino Real, San Bruno, CA, United States",
            "startTime": "2014-07-28T04:45:00.000Z",
            "customData": {
                "title": "Active Activity"
            },
            "modified": "2014-07-23T13:26:41.000Z"
        }],
        "senderId": "Johnny.Appleseed",
        "status": 8
}

SQLite File: enter image description here

I have the following entities:

meeting
activity
customData

relationships:

meeting has to-many relationship with activity called activities

activity has to-many relationship with customData

Of course, there is an inverse relationship for each relationship.

customData entity only has one attribute called title

Here is my customData.h

@class Activity;

@interface customData : NSManagedObject

@property (nonatomic, retain) NSString * title;
@property (nonatomic, retain) Activity *activity;

@end

RESKit Mapping:

+(RKEntityMapping *)customDataMapping:(RKEntityMapping *)customDataMapping;
{
    [customDataMapping addAttributeMappingsFromDictionary:@{@"title":@"title"}];
    customDataMapping.identificationAttributes = @[@"title"];
    return customDataMapping;
}

ObjectManager:

                meetingMapping = [RESTMappingProvider meetingPutMapping:meetingMapping];
                activityMapping = [RESTMappingProvider activityPutMapping:activityMapping];
                customDataMapping = [RESTMappingProvider customDataMapping:customDataMapping];

                [activityMapping  addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:kCustomDataRelationship
                                                                                                 toKeyPath:kCustomDataRelationship
                                                                                               withMapping:customDataMapping]];

                [meetingMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:kActivitiesRelationship
                                                                                                  toKeyPath:kActivitiesRelationship
                                                                                                withMapping:activityMapping]];

                RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:[meetingMapping inverseMapping] objectClass:[Meeting class] rootKeyPath:nil method:RKRequestMethodAny];

                NSIndexSet *statusCodeSet = RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful);

                RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:meetingMapping
                                                                                                        method:RKRequestMethodAny
                                                                                                   pathPattern:kMeetupKeyPath
                                                                                                       keyPath:nil
                                                                                                   statusCodes:statusCodeSet];

                objectManager.requestSerializationMIMEType = RKMIMETypeJSON;
                [objectManager addRequestDescriptor:requestDescriptor];
                [objectManager addResponseDescriptor:responseDescriptor];
                [objectManager.HTTPClient  registerHTTPOperationClass:[AFHTTPRequestOperation class]];

                [objectManager putObject:anInvite path:kMeetupKeyPath parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
                    NSLog (@"******* OUTBOX OBJECT PUT **********");

                } failure:^(RKObjectRequestOperation *operation, NSError *error) {


                }];
            }
        }
    }
});

Problem: For some reason, I'm losing relationships between an activity and customData object. As you can see, the internal ID (ZACTIVITY) for CoreData does not always assign Ids, thus, I lose objects because relationships are no longer there. I think its during the PUT call that objects are not assigned the ids.

I read on RESKit forums about using @parent and @metadata, but I'm not sure how to use it, or if that's even a right approach. Please advise.


Solution

  • I'm guessing that the titles of your custom data are not always unique, so, because you use customDataMapping.identificationAttributes = @[@"title"]; and a 1:many relationship some instances of custom data will be disconnected from their old relationship and connected to a new one.

    Probably you should remove the identificationAttributes and add a fetch request block which purges out any orphan custom data objects (ones where the relationship is nil) after the data is collected.