Вы можете использовать интерфейс Codable с объектами CoreData для кодирования и декодирования данных, однако он не такой автоматический, как при использовании с простыми старыми быстрыми объектами. Вот как можно реализовать декодирование JSON напрямую с объектами Core Data:
Во-первых, вы заставляете свой объект реализовывать Codable. Этот интерфейс должен быть определен в объекте, а не в расширении. Вы также можете определить свои ключи кодирования в этом классе.
class MyManagedObject: NSManagedObject, Codable {
@NSManaged var property: String?
enum CodingKeys: String, CodingKey {
case property = "json_key"
}
}
Затем вы можете определить метод инициализации. Это также должно быть определено в методе класса, поскольку метод init требуется протоколом Decodable.
required convenience init(from decoder: Decoder) throws {
}
Однако правильный инициализатор для использования с управляемыми объектами:
NSManagedObject.init(entity: NSEntityDescription, into context: NSManagedObjectContext)
Итак, секрет здесь в том, чтобы использовать словарь userInfo для передачи соответствующего объекта контекста в инициализатор. Для этого вам нужно расширить структуру CodingUserInfoKey
новым ключом:
extension CodingUserInfoKey {
static let context = CodingUserInfoKey(rawValue: "context")
}
Теперь вы можете просто в качестве декодера контекста:
required convenience init(from decoder: Decoder) throws {
guard let context = decoder.userInfo[CodingUserInfoKey.context!] as? NSManagedObjectContext else { fatalError() }
guard let entity = NSEntityDescription.entity(forEntityName: "MyManagedObject", in: context) else { fatalError() }
self.init(entity: entity, in: context)
let container = decoder.container(keyedBy: CodingKeys.self)
self.property = container.decodeIfPresent(String.self, forKey: .property)
}
Теперь, когда вы настраиваете декодирование для управляемых объектов, вам нужно передать соответствующий объект контекста:
let data = //raw json data in Data object
let context = persistentContainer.newBackgroundContext()
let decoder = JSONDecoder()
decoder.userInfo[.context] = context
_ = try decoder.decode(MyManagedObject.self, from: data) //we'll get the value from another context using a fetch request later...
try context.save() //make sure to save your data once decoding is complete
Чтобы закодировать данные, вам нужно сделать что-то подобное, используя функцию протокола encode.
person
casademora
schedule
24.10.2017