问题
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