[iOS] [Swift] CoreData + Codable

TofTof Membre
15 janv. modifié dans Dev. iOS, watchOS, tvOS #1

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

Mots clés:

Réponses

  • Il me semblait qu'avec CoreData on n'avait pas besoin d'utiliser forKey et tout ça ?

  • TofTof Membre

    @Joanna Carter merci pour le lien
    C'est curieux qu'Apple est pas fait un effort pour rendre CoreData compatible avec Codable

  • Joanna CarterJoanna Carter Membre, Modérateur
    19 janv. modifié #5

    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)
      }
    }
    
  • TofTof Membre

    @Joanna Carter sympa le petit exemple :D
    Y a pas moyen d'activer color syntax pour Swift ? Ça serait encore plus chouette :tongue:

Connectez-vous ou Inscrivez-vous pour répondre.