问题
Below is my setup:
- (RKManagedObjectStore *)setupCoreDataWithRESTKit
{
NSError * error;
NSURL * modelURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"App" ofType:@"momd"]];
NSManagedObjectModel * managedObjectModel = [[[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL] mutableCopy];
self.managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel];
[self.managedObjectStore createPersistentStoreCoordinator];
NSArray * searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString * documentPath = [searchPaths objectAtIndex:0];
NSPersistentStore * persistentStore = [self.managedObjectStore addSQLitePersistentStoreAtPath:[NSString stringWithFormat:@"%@/App%@.sqlite", documentPath, [TBSPersistence username]] fromSeedDatabaseAtPath:nil withConfiguration:nil options:[self optionsForSqliteStore] error:&error];
NSAssert(persistentStore, @"Failed to add persistent store with error: %@", error);
NSLog(@"Path: %@", [NSString stringWithFormat:@"%@/App%@.sqlite", documentPath, [TBSPersistence username]]);
if(!persistentStore){
NSLog(@"Failed to add persistent store: %@", error);
}
[self.managedObjectStore createManagedObjectContexts];
return self.managedObjectStore;
}
POST Invite -- Invite has a to-many relationship with Activity::
-(void)sendInvite:(NSInteger)methodType
{
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
self.objectManager = [self getObjectManager];
self.objectManager.managedObjectStore = appDelegate.managedObjectStore;
RKEntityMapping *invitationMapping = [RKEntityMapping mappingForEntityForName:kInvite
inManagedObjectStore:self.objectManager.managedObjectStore];
RKEntityMapping *activityMapping = [RKEntityMapping mappingForEntityForName:kActivity
inManagedObjectStore:self.objectManager.managedObjectStore];
Invite *invitation;
invitationMapping = [RESTMappingProvider invitionPostMapping:invitationMapping];
invitationMapping.identificationAttributes = @[@"inviteId"];
activityMapping = [RESTMappingProvider activityPostMapping:activityMapping];
activityMapping.identificationAttributes = @[@"activityId"];
[invitationMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:kActivitiesRelationship
toKeyPath:kActivitiesRelationship
withMapping:activityMapping]];
invitation = [self setupInviteProperties:STPOST];
[self setupDescriptors:invitationMapping andKeyPath:kKeyPath descriptorClass:0];
[self.objectManager.HTTPClient registerHTTPOperationClass:[AFHTTPRequestOperation class]];
[self.objectManager postObject:invitation path:kKeyPath parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
}
failure:^(RKObjectRequestOperation *operation, NSError *error) {
}];
}
}
Descriptor:
-(void)setupDescriptors:(RKEntityMapping *)invitationMapping andKeyPath:(NSString *)keyPath descriptorClass:(BOOL)isTemplate
{
RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:[invitationMapping inverseMapping] objectClass:[Invite class] rootKeyPath:nil method:RKRequestMethodAny];
NSIndexSet *statusCodeSet = RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful);
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:invitationMapping
method:RKRequestMethodGET
pathPattern:keyPath
keyPath:nil
statusCodes:statusCodeSet];
self.objectManager.requestSerializationMIMEType = RKMIMETypeJSON;
[self.objectManager addRequestDescriptor:requestDescriptor];
[self.objectManager addResponseDescriptor:responseDescriptor];
}
I POST
just fine. When I get a Response
, I get the assigned ID's, for the created objects in the database, back from the server.
POSTING:
@"inviteId" : @"0" @"activityId" : @"0"
In response, I get everything back as POSTED, however, the server issues Real IDs.
RESPONSE:
@"inviteId" : @"123456" @"activityId" : @"234567"
Problem:
invite
Object gets updated with the assigned ID auto-magically; however, the activity objects become duplicates in CoreData (.sqlite) with one of the duplicate will have @"0"
as the activityID
, while its duplicate will have the assigned Id @"234567"
Later when I GET, only the assigned Id object (
@"234567") get updated. Objects with
@"0"` Id's are never touched and remain in Core Data.
Question: How can I avoid the duplicate record and why is this not happening to the invite
Object
* UPDATE *
Returned JSON:
{
"inviteId": 226,
"meetingType": 2,
"activities": [{
"locationAddress": "4th Floor",
"startTime": "2014-05-07T01:15:23Z",
"activityId": 263,
"latitude": "0",
"longitude": "0",
"meetupId": 226,
"locationName": "West Conference Room",
"oldId": -7360
}, {
"locationAddress": "123 Main St. ",
"startTime": "2014-05-06T20:15:45Z",
"activityId": 264,
"latitude": "0",
"longitude": "0",
"meetupId": 226,
"locationName": "Starwood Building",
"oldId": -9325
}],
"comment": "Comments",
"status": 0,
"senderId": "Userid",
"startDate": "2014-05-07T13:15:00Z"
}
activities
is the name of the relationship between Invite
& Activity
entities
回答1:
This is the expected (if perhaps not ideal) outcome - RestKit is only able to map the response onto the sent object (not its relationships).
A good option could be to use fetch request blocks to find and purge the orphan activity objects at a later date (it wouldn't run after the POST, so you would need to manually find and delete if you needed the dead objects removed immediately).
来源:https://stackoverflow.com/questions/23485863/restkit-duplicate-objects-in-relationship-after-post