【问题标题】:How to store JSON decodable values into Coredata using Swift如何使用 Swift 将 JSON 可解码值存储到 Coredata
【发布时间】:2020-04-25 00:50:52
【问题描述】:

我正在尝试将JSON 数据加载到CoreData。在这里,我使用 JSON structure 进行解码,然后我尝试将 decodable 数据提取到 CoreData 中。我不知道如何将 decodeable 与 iterate 数据一起使用并提取到 coredata 中。下面的代码我试过了,但没有得到正确的结果。请帮我解决这个问题。

我的 JSON

{
    "status": true,
    "data": [
        {
            "id": "20",
            "name": "ar1"
        },
        {
            "id": "21",
            "name": "ar2"
        },
        {
            "id": "22",
            "name": "ar3"
        }
    ]
}

我的 JSON 结构

struct userList: Codable {
    let status: Bool
    let data: [userData]
}

struct userData: Codable {
    let id, name: String
}

我的 Coredata 实体

var users = [User]() // User is my entity name

JSON 可编码并尝试加载到 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)
}

【问题讨论】:

  • 请解释您的代码的哪一部分不起作用。目前还不是很清楚你在问什么。 “here I am dong errors”和 Cant able to get values“没有帮助,您需要更具体。另见How to Ask
  • @vadian 你能帮我解决这个问题吗?

标签: ios json swift core-data


【解决方案1】:

为了能够将 JSON 直接解码为 Core Data 类,您必须采用 Decodable

  • 实现两个扩展,以便能够通过JSONDecoder 传递托管对象上下文

    extension CodingUserInfoKey {
        static let context = CodingUserInfoKey(rawValue: "context")!
    }
    
    extension JSONDecoder {
        convenience init(context: NSManagedObjectContext) {
            self.init()
            self.userInfo[.context] = context
        }
    }
    
  • User 中采用Decodable 并添加CodingKeys 和所需的init(from 方法

    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)
        }
    ...
    
  • 现在您只需要一个用于根对象的伞形结构。再次请始终以大写字母开头的结构命名

    struct Root: Decodable {
        let status: Bool
        let data: [User]
    }
    
  • 要使用自定义初始化程序解码 JSON,User 实例会自动插入到数据库中

    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)
    

【讨论】:

  • 非常感谢。我会尽力在这里更新你。
猜你喜欢
  • 1970-01-01
  • 2020-03-03
  • 2019-02-28
  • 2016-04-26
  • 1970-01-01
  • 2015-09-11
  • 1970-01-01
  • 2016-08-14
  • 1970-01-01
相关资源
最近更新 更多