Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mantle and Core Data - update instead of delete/create

Is there a way in mantle to update an existing record in core data instead of always create new ones? This blog post looks promising, but I don't find the method updateWithJSON: somewhere in Mantle. Right now, I'm doing the following:

MantleObject *mantleObject = [MTLJSONAdapter modelOfClass:[MantleObject class] fromJSONDictionary:dictionary error:NULL];
CoreDataObject *coreDataObject = [CoreDataObject MR_findFirstByAttribute:@"primaryKey" withValue:mantleObject.primaryKey];

// avoid duplicates
if (coreDataObject != nil) {
    [coreDataObject MR_deleteEntity];
}

[MTLManagedObjectAdapter managedObjectFromModel:mantleObject insertingIntoContext:[NSManagedObjectContext MR_contextForCurrentThread] error:NULL];

It works as expected, but I don't like the idea of always deleting and creating the 'same' object over and over again. So I would love to have the opportunity of updating existing objects (overwriting is fine; ALL the values of the new object can replace the existing ones).

like image 276
swalkner Avatar asked Mar 19 '14 23:03

swalkner


2 Answers

Mantle has supported updating managed objects since version 1.3.

Your model classes need to implement the MTLManagedObjectSerializing protocol method propertyKeysForManagedObjectUniquing and return the property keys which identify a model, which in your case appears to primaryKey:

+ (NSSet *)propertyKeysForManagedObjectUniquing {
    return [NSSet setWithObject:@"primaryKey"];
}

The header doc explains how it works, but basically the MTLManagedObjectAdapter will fetch an existing managed object if one exists and update that object rather than create a new one.

I would recommend using Mantle's built in support, rather than trying to find duplicates yourself. This will result in simpler, more maintainable code.

like image 134
David Snabel-Caunt Avatar answered Sep 21 '22 21:09

David Snabel-Caunt


I know nothing about "mantle" or "MagicalRecord" but ...

This looks very costly indeed.
It looks as if you fetched the existing item already (in order to delete it), the missing step would be to get all properties from your MantleObject and update the existing item.

As far as CoreData goes, you could:

  1. perform the insert as you do now (keep a reference to the new object newObj)
  2. keep an array of all the managed object property keys/names you like to import props = @[@"prop1",@"prop2", ...]
  3. get the values by using dict = [newObj committedValuesForKeys:props]
  4. update the existing object [existing setValuesForKeysWithDictionary:dict]
  5. delete the newObj [context deleteObject:newObj]

if there is no existing object, simply don't delete the new object

like image 36
Dan Shelly Avatar answered Sep 21 '22 21:09

Dan Shelly