如何使用 Swift 将 JSON 可解码值存储到 Coredata 中

Tim*_*Tim 3 json core-data ios swift

我正在尝试将JSON数据加载到CoreData. 在这里,我使用 JSONstructure进行解码,之后我尝试将decodable数据提取到 CoreData 中。我不\xe2\x80\x99t 知道如何使用可解码的iterate数据并获取核心数据。我尝试了下面的代码,但没有得到正确的结果。请帮我解决这个问题。

\n\n

我的 JSON

\n\n
{\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0"status":\xc2\xa0true,\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0"data":\xc2\xa0[\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0{\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0"id":\xc2\xa0"20",\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0"name":\xc2\xa0"ar1"\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0},\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0{\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0"id":\xc2\xa0"21",\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0"name":\xc2\xa0"ar2"\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0},\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0{\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0"id":\xc2\xa0"22",\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0"name":\xc2\xa0"ar3"\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0}\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0]\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

我的 JSON 结构

\n\n
struct userList: Codable {\n    let status: Bool\n    let data: [userData]\n}\n\nstruct userData: Codable {\n    let id, name: String\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

我的核心数据实体

\n\n
var users = [User]() // User is my entity name\n
Run Code Online (Sandbox Code Playgroud)\n\n

JSON 可编码并尝试加载到 CoreData 中

\n\n
do {\n       let result = try JSONDecoder().decode(userList.self, from:data) // here I am dong mistakes.\n       let status = result.status\n       if status == true {\n           let newPerson = User(context: self.context)\n           newPerson.id = "" // Cant able to get values\n           newPerson.name = ""\n           self.users.append(newPerson)\n\n            DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {\n                self.tableView.reloadData()\n             }\n            } else {\n               print(error)\n             }\n\n    } catch {\n         print(error)\n}\n
Run Code Online (Sandbox Code Playgroud)\n

vad*_*ian 6

为了能够将 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
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 采用并添加所需User的方法DecodableCodingKeysinit(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)
        }
    ...
    
    Run Code Online (Sandbox Code Playgroud)
  • 现在,根对象只需要一个伞形结构。再次请始终以大写字母开头命名结构

    struct Root: Decodable {
        let status: Bool
        let data: [User]
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 要解码 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)
    
    Run Code Online (Sandbox Code Playgroud)