Codable and NSManaged subclass with separate saving and decoding operations

冷暖自知 提交于 2019-12-24 17:12:59

问题


My requirement is that I will get some JSON data from the server and I need to decode it and sometimes save it to CoreData. This is to ensure that I don't need to keep 2 separate Models each for Decoding and CoreData but one that will handle both.

I went through a few threads related to Codable CoreData but what they offer is that everytime we are performing Decoding, the object gets saved to the CoreData(which first of all is not what I want and second it creates duplicate entries) like this

I wanted something like If you want to just decode the data, do this, If you want to save the data do this but using the same Model type.

The code that I've been following :

public extension CodingUserInfoKey {
    // Helper property to retrieve the context
    static let managedObjectContext = CodingUserInfoKey(rawValue: "managedObjectContext")
}

public class Employee: NSManagedObject, Codable {

    @NSManaged public var employeeID: Int16
    @NSManaged public var personalDetails: PersonalDetails?

    private enum CodingKeys: String, CodingKey {
        case employeeID
        case personalDetails
    }

    public required convenience init(from decoder: Decoder) throws {

        guard let codingUserInfoKeyManagedObjectContext = CodingUserInfoKey.managedObjectContext,
            let managedObjectContext = decoder.userInfo[codingUserInfoKeyManagedObjectContext] as? NSManagedObjectContext,
            let entity = NSEntityDescription.entity(forEntityName: "DBEmployee", in: managedObjectContext) else {
            fatalError("Failed to decode User")

        }

        self.init(entity: entity, insertInto: managedObjectContext)

        let container = try decoder.container(keyedBy: CodingKeys.self)
        self.employeeID = try container.decodeIfPresent(Int16.self, forKey: .employeeID)!
        self.personalDetails = try container.decodeIfPresent(PersonalDetails.self, forKey: .personalDetails)

    }


    public func encode(to encoder: Encoder) throws {

        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(employeeID, forKey: .employeeID)
        try container.encode(personalDetails, forKey: .personalDetails)

    }

}

Now my problem arises when I just want to Decode the data and not save to Core Data. Since I am just decoding, I will not assign any managedObjectContext but when decoder is called, it will look for context, will not find one and will crash

I was thinking of handling whether the managedObjectContext exists inside the userInfo of decoder and if not, just use normal decoder which we generally use for Decodable protocol but because of the convenience init, it won't allow me to leave without self.init.

Is there any workaround that any of you have worked upon ?

来源:https://stackoverflow.com/questions/59405554/codable-and-nsmanaged-subclass-with-separate-saving-and-decoding-operations

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!