iosswiftcore-datainitialization

Swift CoreData create or update entity from JSON


I'm working with CoreData Project and JSON response from server. My objective is create an Entity failable initializer from JSON parameter which will first check if entity already exist (by check property "id" compare to json["id] field). If entity already exist. the initializer will only update entity with JSON. If entity did not exist, the initializer will create a new entity and update property of new entity with the JSON.

How can I create the failable initializer?

I have tried this but don't know it is correct or not (Have some unwrap optional.

import SwiftyJSON
import CoreData

extension Movie {
    struct Keys {
        static let id = "id"
        static let title = "title"
    }
    
    convenience init?(in context: NSManagedObjectContext!, with json: JSON?) {
        
        self.init(entity: NSEntityDescription.entity(forEntityName: "Movie", in: context)!, insertInto: context)
        guard let json = json else {
            return nil
        }
        id = json[Keys.id].numberValue
        title = json[Keys.title].string
        
    }
    
    func update(from json: JSON?) {
        guard let json = json else {
            return
        }
        
        id = json[Keys.id].numberValue
        title = json[Keys.title].string
    }

}

Solution

  • I don't believe that the init is the right place to look for an existing object.

    What I would do is add a class func to Movie that finds or creates a Movie object, something like:

    /// Returns an existing Movie if the id exists, or a new one if not.
    /// Can return nil if json is nil or missing keys
    class func findOrCreate(in context: NSManagedObjectContext!, with json: JSON?) -> Movie? {
        // If JSON is nil, return nil
        //  (your code here)
        // Look for an existing movie and return it if you find one
        //  (your code here)
    
        // If there is no existing one call the init
        return Movie(in: content, with: json)
    }