Imagine the following relation in CoreData
Recipe < --- >> Ingredient
I'm using MagicalRecord to regularly import the server database (JSON API) with my local CoreData database.
So, if I import Recipe 1 with Ingredient 1 like this:
{
id:1,
name: "Recipe 1",
ingredients: [{
name: 'Ingredient 1'
}]
}
So for so good, MagicalRecord creates the two entities and links them together.
The problem appears when the server changes to the following:
{
id:1,
name: "Recipe 1",
ingredients: [{
name: 'Ingredient 2' <-- Notice here
}]
}
What MagicalRecord does is create the Ingredient 2record (correct), link it to be the only ingredient for Recipe 1(correct). But if I search for Ingredients, I found 2 records on my CoreData database.
So the questions is, is it possible to keep track of "deleted" objects when importing, and deleting them?
The real problem here is that MagicalRecord seems to be importing duplicates. This problem should have been resolved in a recent update, however, if you're still having issues, I suggest opening a ticket on the project issues page
I have worked around this problem by following this process.
This approach should achieve the desired behaviour for any given request. Just be aware you will still possibly be deleting records referenced from elsewhere, so only use this approach if they can be recreated by other future requests.
Import Code
NSArray *existingObjectIDs = [self existingObjectIDsForYourQuery];
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
[Recipe MR_importFromObject:response inContext:localContext];
NSArray *objectIDs = [[[localContext updatedObjects] allObjects] valueForKey:@"objectID"];
[self deleteLocalObjectsWithObjectIDs:existingObjectIDs excludingImportedObjectIDs:objectIDs];
}];
Delete Code
- (void)deleteLocalObjectsWithObjectIDs:(NSArray *)existingObjectIDs excludingImportedObjectIDs:(NSArray *)importedObjectIDs {
NSMutableArray *objectsToDelete = [NSMutableArray arrayWithArray:existingObjectIDs];
for ( NSManagedObjectID *objectID in importedObjectIDs ) {
[objectsToDelete removeObject:objectID];
}
[MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext) {
for ( NSManagedObjectID *objectID in objectsToDelete ) {
NSManagedObject *object = [localContext existingObjectWithID:objectID error:nil];
if ( object ) {
[localContext deleteObject:object];
}
}
}];
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With