Question

I am using RestKit 0.20.3 for my application. It has offline mode, so I have to store objects in local coredata.

Whenever some objects are deleted from server, it sends deleted = true attribute in JSON, which I handle in mapping with deletionPredicate. Here is my mapping.

- (RKEntityMapping *)meetingsMapping {

    RKEntityMapping *meetingsMapping = [RKEntityMapping mappingForEntityForName:@"DBMeetings" inManagedObjectStore:objectManager.managedObjectStore];
    meetingsMapping.setDefaultValueForMissingAttributes = NO;
    meetingsMapping.deletionPredicate = [NSPredicate predicateWithFormat:@"shouldBeDeleted = 1"];
    [meetingsMapping setModificationAttributeForName:@"updated_at"];
    meetingsMapping.identificationAttributes = @[@"id"];

    [meetingsMapping addAttributeMappingsFromDictionary:@{
                                                      @"id": @"id",
                                                      @"title": @"title",

                                                      @"start_date_human": @"start_date_human",
                                                      @"start_time_human": @"start_time_human",
                                                      @"finish_date_human": @"finish_date_human",
                                                      @"finish_time_human": @"finish_time_human",

                                                      @"lock": @"lock",
                                                      @"location": @"location",
                                                      @"sample": @"sample",

                                                      @"deleted": @"shouldBeDeleted",

                                                      @"created_at": @"created_at",
                                                      @"updated_at": @"updated_at",
                                                      @"follow_up_id": @"follow_up_id",
                                                      @"total_topics": @"total_topics",
                                                      }];

[meetingsMapping addRelationshipMappingWithSourceKeyPath:@"tags" mapping:[self tagsMapping]];
[meetingsMapping addRelationshipMappingWithSourceKeyPath:@"required_participants" mapping:[self contactsMapping]];
[meetingsMapping addRelationshipMappingWithSourceKeyPath:@"optional_participants" mapping:[self contactsMapping]];
[meetingsMapping addRelationshipMappingWithSourceKeyPath:@"readonly_participants" mapping:[self contactsMapping]];
[meetingsMapping addRelationshipMappingWithSourceKeyPath:@"organizer" mapping:[self contactsMapping]];

return meetingsMapping;

}

It is working well, and attributes are removed from local CoreData.

The problem is the method getObjectsAtPath still returns all objects in mappingResult parameter.

[[RKObjectManager sharedManager] getObjectsAtPath:[NSString stringWithFormat:@"%@?type=past&page=%i", URL_MEETINGS, pageNo]
                                       parameters:nil
                                          success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
                                              KLog(@"%@", mappingResult.array); // It is returning all objects, not only non-deleted objects 
                                              completionHandler(mappingResult.array, nil);
                                          }
                                          failure:^(RKObjectRequestOperation *operation, NSError *error) {
                                              completionHandler(nil, error);
                                          }];   

Suppose if 5 out of 20 objects were deleted, mappingResult.array returns 20 records not 15. The 5 deleted records have no data. When I Log mappingResult.array, the first 5 records are printed as following:

2014-03-27 13:10:14.105 MeetingKing[7851:70b] W restkit.network.core_data:RKManagedObjectRequestOperation.m:125 Unable to refetch managed object <DBMeetings: 0xc1cb820> (entity: DBMeetings; id: 0xc1a6a60 <x-coredata://7B9FC7F6-C0E9-4DF5-91AC-D7C49F54B4F5/DBMeetings/t2915CF2E-2D7D-4E29-8B39-B1C51151809410> ; data: <fault>): the object has a temporary managed object ID.
2014-03-27 13:10:14.105 MeetingKing[7851:70b] W restkit.network.core_data:RKManagedObjectRequestOperation.m:125 Unable to refetch managed object <DBMeetings: 0xc5b2ed0> (entity: DBMeetings; id: 0xc5d1110 <x-coredata://7B9FC7F6-C0E9-4DF5-91AC-D7C49F54B4F5/DBMeetings/t2915CF2E-2D7D-4E29-8B39-B1C51151809416> ; data: <fault>): the object has a temporary managed object ID.
2014-03-27 13:10:14.106 MeetingKing[7851:70b] W restkit.network.core_data:RKManagedObjectRequestOperation.m:125 Unable to refetch managed object <DBMeetings: 0xc58b6a0> (entity: DBMeetings; id: 0xc5d3de0 <x-coredata://7B9FC7F6-C0E9-4DF5-91AC-D7C49F54B4F5/DBMeetings/t2915CF2E-2D7D-4E29-8B39-B1C51151809417> ; data: <fault>): the object has a temporary managed object ID.
2014-03-27 13:10:14.106 MeetingKing[7851:70b] W restkit.network.core_data:RKManagedObjectRequestOperation.m:125 Unable to refetch managed object <DBMeetings: 0xc5b50e0> (entity: DBMeetings; id: 0xc5d4af0 <x-coredata://7B9FC7F6-C0E9-4DF5-91AC-D7C49F54B4F5/DBMeetings/t2915CF2E-2D7D-4E29-8B39-B1C51151809419> ; data: <fault>): the object has a temporary managed object ID.
2014-03-27 13:10:14.107 MeetingKing[7851:70b] W restkit.network.core_data:RKManagedObjectRequestOperation.m:125 Unable to refetch managed object <DBMeetings: 0xc1ed5a0> (entity: DBMeetings; id: 0xc1c84e0 <x-coredata://7B9FC7F6-C0E9-4DF5-91AC-D7C49F54B4F5/DBMeetings/t2915CF2E-2D7D-4E29-8B39-B1C51151809422> ; data: <fault>): the object has a temporary managed object ID.

If I check in DB, there are only 15 records. That's OK.

If I explicitly fetch from DB, it returns 15 records only, That's OK

But in getObjectsAtPath callback, the mappingResult.array parameter returns 20 records. That's not OK. :(

The problem is count of mappingResult.array becomes 20 and my UITableView displays 20 rows, with 5 rows have no data.

Is there any other callback by RestKit that accurately returns 15 records, so that I would not have to explicitly fetch records from DB?

Was it helpful?

Solution

The mappingResult is returning the objects that were mapped, that is what it's supposed to do. The fact that some items were subsequently deleted doesn't change that - indeed you have all of the information that you need as you know all of the objects that were mapped and which ones were deleted as a result.

The simple solution is to use an NSFetchedResultsController to source data for your table view. It will deal correctly with the updates, insertions and deletions and you don't need to do additional work.

Alternatively, you would need to iterate mappingResult.array and filter out the deleted items. The best way to verify is to use a check:

if (item.isDeleted || item.managedObjectContext == nil) {
    // remove the now invalid item...
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top