问题
I am trying to load JSON Data into CoreData. Here, I used JSON structure for decodable and after that I am trying to fetch the decodable Data into CoreData. I don’t know how to use decodable with iterate the data and fetching into coredata. Below code I tried, but not getting proper result. Please help me to resolve this.
My JSON
{
"status": true,
"data": [
{
"id": "20",
"name": "ar1"
},
{
"id": "21",
"name": "ar2"
},
{
"id": "22",
"name": "ar3"
}
]
}
My Structure For JSON
struct userList: Codable {
let status: Bool
let data: [userData]
}
struct userData: Codable {
let id, name: String
}
My Coredata Entity
var users = [User]() // User is my entity name
JSON Codable and Try ing to Load Into CoreData
do {
let result = try JSONDecoder().decode(userList.self, from:data) // here I am dong mistakes.
let status = result.status
if status == true {
let newPerson = User(context: self.context)
newPerson.id = "" // Cant able to get values
newPerson.name = ""
self.users.append(newPerson)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
self.tableView.reloadData()
}
} else {
print(error)
}
} catch {
print(error)
}
回答1:
To be able to decode JSON directly into Core Data classes you have to adopt Decodable
Implement two extensions to be able to pass the managed object context via the
JSONDecoderextension CodingUserInfoKey { static let context = CodingUserInfoKey(rawValue: "context")! } extension JSONDecoder { convenience init(context: NSManagedObjectContext) { self.init() self.userInfo[.context] = context } }In
UseradoptDecodableand addCodingKeysand the requiredinit(frommethodpublic class User: NSManagedObject, Decodable { private enum CodingKeys: String, CodingKey { case name, id } public required convenience init(from decoder: Decoder) throws { guard let context = decoder.userInfo[.context] as? NSManagedObjectContext else { fatalError("Error: with managed object context!") } let entity = NSEntityDescription.entity(forEntityName: "User", in: context)! self.init(entity: entity, insertInto: context) let values = try decoder.container(keyedBy: CodingKeys.self) name = try values.decode(String.self, forKey: .name) id = try values.decode(String.self, forKey: .id) } ...Now you need only one umbrella struct for the root object. Once again please name structs always with starting uppercase letter
struct Root: Decodable { let status: Bool let data: [User] }To decode the JSON use the custom initializer, the
Userinstances are inserted automatically into the databasedo { let decoder = JSONDecoder(context: context) // context is the NSManagedObjectContext instance let result = try decoder.decode(Root.self, from: data) if result.status { print("success") try context.save() } catch { print(error)
来源:https://stackoverflow.com/questions/59629695/how-to-store-json-decodable-values-into-coredata-using-swift