1
votes

Comment enregistrer un dictionnaire dans les données de base dans Swift

Quelle est la meilleure méthode pour enregistrer un dictionnaire à l'aide de Core Data? J'ai un dictionnaire défini comme

var myRecipes:[String:[Recipe]]

Où Recipe est une structure avec des informations de santé sur une recette. La chaîne serait une catégorie comme "Petit-déjeuner" ou "Déjeuner" et le tableau Recette contiendrait des recettes pour le petit-déjeuner ou le déjeuner.

Quelle serait la meilleure façon d'ajouter de nouvelles catégories et d'ajouter des recettes à des catégories dans Core Data?


1 commentaires

C'est un peu trop large, avez-vous pour l'instant quelque chose comme un modèle de données et du code pour gérer vos entités?


3 Réponses :


1
votes

Vous pouvez sérialiser votre dictionnaire en données et l'enregistrer dans les données de base pour une utilisation ultérieure. Voici un exemple:

struct Recipe: Codable {
    let identify: String
    let name: String
}

let myRecipes:[String:[Recipe]] = ["key_1": [Recipe(identify: "r_1", name: "r_name_1")],
                                   "key_2": [Recipe(identify: "r_2", name: "r_name_2"),
                                             Recipe(identify: "r_3", name: "r_name_3")]]
let jsonData = try! JSONEncoder().encode(myRecipes) // Save this value (type: Data) to core data.
// later when you want to construct your Dictionary back, use following code:
let result = try! JSONDecoder().decode([String: [Recipe]].self, from: jsonData) // `jsonData` here is retrieved from core data.

Mais pourquoi ne pas créer 2 entités séparées ( Category et Recipe ) pour elles? Ce qui, je pense, rend les choses beaucoup plus claires.

Bon codage!


0 commentaires

1
votes
  • Dans Core Data, créez deux entités Category et Recipe .
  • Dans Category , déclarez un attribut name et une relation non facultative vers plusieurs recettes à Recipe .
  • Dans Recipe , déclarez les attributs requis et une relation optionnelle à un category à Category .

Je recommande de créer manuellement les sous-classes NSManagedObject ( Codegen Manual / None et menu Editor> Create NSManagedObject Subclass ... ). Ensuite, vous pouvez déclarer la relation to-many comme Set natif plutôt que comme NSSet sans type.


0 commentaires

1
votes

Vous ne pouvez pas stocker directement le dictionnaire ou le tableau dans les données de base. Vous pouvez créer une classe ou une structure pour obtenir la même chose, puis ajouter les propriétés requises. Ci-dessous, je vous donne l'exemple. Vous devez créer un attribut avec le type Transformable dans Entité.

 entrez la description de l'image ici p>

 // logic of fetc logic which will return array of type Task object i.e [Task]
    for i in (0..<tasksFromDatabase!.count) {
          var innerArray = [FleetInfoDetails]()
           let taskData = NSData(data: tasksFromDatabase?[i].value(forKey: "task_object") as! Data) as Data
            let taskDetails = NSKeyedUnarchiver.unarchiveObject(with: taskData) as! FleetInfoDetails
        }

// Comment enregistrer

        let entityDescription = NSEntityDescription.entity(forEntityName: "Task", in: taskManagedContext) // use your managedcontext
        let data = Task(entity: entityDescription!, insertInto: taskManagedContext)// managedcontext
        data.task_object = NSKeyedArchiver.archivedData(withRootObject: taskDetails) as NSObject
do {
            try youManagedContext.save() // user your managedcontext
            return true
        } catch {
               print(error.localizedDescription)
        }

Comment récupérer les données. Vous devez désarchiver l'objet.

//Task+CoreDataProperties.swift
    import Foundation
    import CoreData

    extension Task {
        @NSManaged var task_object: NSObject?
    }
// class FleetInfoDetails
      class FleetInfoDetails: NSObject, NSCoding {
        var fleetActions = [Int: FleetActions]() // here i am using another type you use according to your use.
        required init(coder aDecoder: NSCoder) {
            fleetActions = aDecoder.decodeObject(forKey: "fleetActions") as? [Int : FleetActions] ?? [Int : FleetActions]()
        }
        func encode(with aCoder: NSCoder) {
            aCoder.encode(fleetActions, forKey: "fleetActions")
        }
        init(json: NSDictionary) {
            self.fleetActions.removeAll()
            if let value = json["fleet_actions"] as? [[String:Any]] {
                for action in value {
                    let currentAction = FleetActions(json: action)
                    self.fleetActions[currentAction.actionType] = currentAction
                }
            }
        }
    }
  // class FleetActions

        class FleetActions: NSObject, NSCoding {
            var actionType: Int = 0

            required init?(coder aDecoder: NSCoder) {
                actionType = aDecoder.decodeObject(forKey: "actionType") as? Int ?? 0
            }

            func encode(with aCoder: NSCoder) {
                aCoder.encode(actionType, forKey: "actionType")
            }
            init(json: [String:Any]) {
                if let value = json["action_type"] as? Int {
                    self.actionType = value
                }
            }
        }


0 commentaires