I have a restfull application which downloads json content from a web service. The first time I call the web service, I cache all objects in core data. The problem appears when I call again. I need to update the changed ones, delete the ones that are not present and insert all new ones. I am getting all local objects and all received ones, looping for inserting or updating and then deleting the ones that weren't modified. The problem is that my algorithm sucks and it's really inefficient. Which is the best practice to keep core data in sync with the web service?
EDITED:
func updateRestaurantsFromJson(dataArray:[[String: AnyObject]]) {
var currentRestaurants = getAllRestaurants()
for restaurantDictionary in dataArray {
if let restaurant = DBRestaurant.fromJson(restaurantDictionary) {
if let index = find(currentRestaurants, restaurant) {
currentRestaurants.removeAtIndex(index)
}
}
}
removeRestaurants(currentRestaurants)
}
I am creating an array of all current objects, inserting/updating in DBRestaurant.fromJson and deleting the untouched ones.
class func fromJson(data: [String: AnyObject]) -> DBRestaurant? {
if let id = data["id"] as? String {
var obj = DBRestaurant.withId(id)
var result: DBRestaurant
if obj == nil {
result = newRestaurant()
result.restaurantID = id
} else {
result = obj!
}
result.updateWithJson(data)
DataManager.save(nil)
return result
} else {
return nil
}
}
class func withId(id: String) -> DBRestaurant? {
let fetchRequest = NSFetchRequest(entityName: kDBRestaurant)
fetchRequest.predicate = NSPredicate(format: "restaurantID = %@", id)
let restaurant = (self.managedObjectContext.executeFetchRequest(fetchRequest, error: nil) as! [DBRestaurant]).first
return restaurant
}
As you fetch your data in JSON, I assume you are working with Key: value data. If that's the case, I would give each object you're storing an
identifier
property. This can be anything, like a string or int, that you app can use to identify the object.Then, if you fetch your objects, you can just compare the identifier of the fetched object to the identifier of the object you have in CoreData:
Although this sounds simple, In all the projects I did with a REST API, these Identifier properties worked for me, and you case seems the same.
Hope it helps