如何在Swift中将字典保存到核心数据

时间:2019-02-18 06:52:33

标签: ios swift

使用Core Data保存词典的最佳方法是什么?我有一本定义为

的字典
var myRecipes:[String:[Recipe]]

“配方”是具有有关配方健康信息的结构。该字符串将是“ Breakfast”或“ Lunch”之类的类别,并且Recipe数组将包含早餐或午餐食谱。

在Core Data中添加新类别和向类别添加配方的最佳方法是什么?

3 个答案:

答案 0 :(得分:1)

  • 在核心数据中创建两个实体CategoryRecipe
  • Category中声明属性name和与recipes的多对非可选关系Recipe
  • Recipe中声明必需的属性以及与categoryCategory的可选一对一关系。

我建议手动创建NSManagedObject子类( Codegen Manual / None 和菜单 Editor> Create NSManagedObject Subclass ... )。然后,您可以将多对多关系声明为本机Set<Recipe>而不是无类型的NSSet

答案 1 :(得分:1)

您不能直接将字典或数组存储到核心数据。您可以创建类或结构以实现相同的目的,然后添加所需的属性。下面我给你例子。您需要在实体中使用 可转换 类型创建属性

enter image description here

//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
                }
            }
        }

//如何保存

        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)
        }

如何获取数据。您需要取消归档该对象。

 // 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
        }

答案 2 :(得分:0)

您可以将“字典”序列化为“数据”,并将其保存到核心数据中以备后用。以下是示例:

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.

但是为什么不为它们创建2个分离的实体(CategoryRecipe)呢?我认为这使事情更加清楚。

编码愉快!