What is the best method to save a dictionary using Core Data? I have a dictionary defined as
var myRecipes:[String:[Recipe]]
Where Recipe is a struct with health information about a recipe. The string would be a category like "Breakfast" or "Lunch" and the Recipe array would have breakfast or lunch recipes.
What would be the best way to add new categories and add recipes to categories in Core Data?
Category
and Recipe
.Category
declare an attribute name
and a to-many non-optional relationship recipes
to Recipe
.Recipe
declare the required attributes and an optional to-one relationship category
to Category
. I recommend to create the NSManagedObject
subclasses manually ( Codegen Manual/None and menu Editor > Create NSManagedObject Subclass... ). Then you are able to declare the to-many relationship as native Set<Recipe>
rather than typeless NSSet
.
You can serialize your Dictionary to Data and save it to core data for later use. Following are example:
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.
However why not creating 2 seperated entities ( Category
and Recipe
) for them? Which I think make thing a lot clearer.
Happy coding!
You can not directly store dictionary or array to core data. You can create class or struct to achieve the same and then add the required properties. Here below i giving you the example. You need to create an attribute with Transformable type in Entity.
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
}
}
}
How to save
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)
}
How to fetch the data You need to unarchived the object.
// 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
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.