简体   繁体   中英

How to store JSON decodable values into Coredata using Swift

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

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 adopt Decodable and add CodingKeys and the required init(from method

     public 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 database

    do { 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)

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM