Update core data from web service. (insert/update/delete)

718 views Asked by At

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
}
1

There are 1 answers

2
Joris416 On

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:

if fetchedObject.identifier == coreDataObject.identifier {
    //you already have the object 
} else {
    //you don't
}

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