问题
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
JSONDecoder
extension CodingUserInfoKey { static let context = CodingUserInfoKey(rawValue: "context")! } extension JSONDecoder { convenience init(context: NSManagedObjectContext) { self.init() self.userInfo[.context] = context } }
In
User
adoptDecodable
and addCodingKeys
and the requiredinit(from
methodpublic 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
User
instances 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