如何在Swift中将字典保存到Core Data?

5
什么是使用Core Data保存字典的最佳方法?我定义了一个字典,如下所示:
var myRecipes:[String:[Recipe]]

Recipe 是一个包含有关食谱健康信息的结构体。字符串将是类别,如“早餐”或“午餐”,而 Recipe 数组将拥有早餐或午餐食谱。

在 Core Data 中添加新类别并将食谱添加到类别中的最佳方法是什么?


1
这个问题太笼统了,你有没有一些数据模型以及处理实体相关的代码? - Joakim Danielson
3个回答

4
  • 在 Core Data 中创建两个实体 CategoryRecipe
  • Category 中声明属性 name 和一个非可选的 to-many 关系 recipesRecipe
  • Recipe 中声明必需的属性和一个可选的 to-one 关系 categoryCategory

我建议手动创建 NSManagedObject 子类(选择 Codegen Manual/None 并在菜单中选择 Editor > Create NSManagedObject Subclass...)。这样你就可以将 to-many 关系声明为原生的 Set<Recipe>,而不是类型不明确的 NSSet


3
你可以将你的字典序列化为数据并保存到核心数据以供以后使用。以下是示例:
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.

但为什么不为它们创建两个单独的实体 (类别食谱)呢?我认为这会使事情更加清晰。

编码愉快!


1
你不能直接将字典或数组存储到核心数据中。你可以创建类或结构体来实现相同的功能,然后添加所需的属性。下面是一个示例。在实体中,你需要创建一个类型为“Transformable”的属性

Entity image

Task+CoreDataProperties.swift

import Foundation
import CoreData

extension Task {
    @NSManaged var task_object: NSObject?
}

FleetInfoDetails.swift

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

FleetActions.swift

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
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接