Bonjour,
En Swift avez vous déjà réussi à faire cohabiter CoreData et Codable en définissante une seule classe pour les deux ?
Si oui quelle est la meilleur manière de procéder ?
Merci pour vos réponses
Mais pourquoi encombrer NSManagedObject avec une capacité qui n'est pas toujours voulu ?
En plus, le init(from decoder: Decoder)ne peut pas se trouver dans une extension et on ne peut pas généraliser le comportement de Codable parce que il faut savoir tous les CodingKeys.
Voici un exemple plus complet :
extension CodingUserInfoKey
{
static let context = CodingUserInfoKey(rawValue: "context")
}
class Address : NSManagedObject, Codable
{
enum CodingKeys: String, CodingKey
{
case line1
}
@NSManaged var line1: String
override init(entity: NSEntityDescription, insertInto context: NSManagedObjectContext?)
{
super.init(entity: entity, insertInto: context)
}
required convenience init(from decoder: Decoder) throws
{
guard let contextUserInfoKey = CodingUserInfoKey.context,
let managedObjectContext = decoder.userInfo[contextUserInfoKey] as? NSManagedObjectContext,
let entity = NSEntityDescription.entity(forEntityName: "Address", in: managedObjectContext) else
{
fatalError("Failed to decode Address!")
}
self.init(entity: entity, insertInto: nil)
let values = try decoder.container(keyedBy: CodingKeys.self)
line1 = try values.decode(String.self, forKey: .line1)
}
func encode(to encoder: Encoder) throws
{
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(line1, forKey: .line1)
}
}
class Person : NSManagedObject, Codable
{
enum CodingKeys: String, CodingKey
{
case name
case age
case address
}
@NSManaged var name: String
@NSManaged var age: Int
@NSManaged var address: Address
override init(entity: NSEntityDescription, insertInto context: NSManagedObjectContext?)
{
super.init(entity: entity, insertInto: context)
}
required convenience init(from decoder: Decoder) throws
{
guard let contextUserInfoKey = CodingUserInfoKey.context,
let managedObjectContext = decoder.userInfo[contextUserInfoKey] as? NSManagedObjectContext,
let entity = NSEntityDescription.entity(forEntityName: "Person", in: managedObjectContext) else
{
fatalError("Failed to decode Person!")
}
self.init(entity: entity, insertInto: nil)
let values = try decoder.container(keyedBy: CodingKeys.self)
name = try values.decode(String.self, forKey: .name)
age = try values.decode(Int.self, forKey: .age)
address = try values.decode(Address.self, forKey: .address)
}
func encode(to encoder: Encoder) throws
{
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(name, forKey: .name)
try container.encode(age, forKey: .age)
try container.encode(address, forKey: .address)
}
}
Réponses
https://medium.com/@kf99916/codable-nsmanagedobject-and-cllocation-in-swift-4-b32f042cb7d3
Il me semblait qu'avec CoreData on n'avait pas besoin d'utiliser forKey et tout ça ?
@Joanna Carter merci pour le lien
C'est curieux qu'Apple est pas fait un effort pour rendre CoreData compatible avec Codable
Mais pourquoi encombrer NSManagedObject avec une capacité qui n'est pas toujours voulu ?
En plus, le
init(from decoder: Decoder)
ne peut pas se trouver dans une extension et on ne peut pas généraliser le comportement de Codable parce que il faut savoir tous les CodingKeys.Voici un exemple plus complet :
@Joanna Carter sympa le petit exemple
Y a pas moyen d'activer color syntax pour Swift ? Ça serait encore plus chouette