Ios 将复杂的JSON保存到Swift中的核心数据

Ios 将复杂的JSON保存到Swift中的核心数据,ios,json,swift,core-data,Ios,Json,Swift,Core Data,我想将来自web服务的JSON结果保存到核心数据,下面是JSON解析的代码 if let jsonResult = try JSONSerialization.jsonObject(with: JSONData!, options: [.mutableContainers]) as? [String: AnyObject] 如果我打印jsonResult,下面是输出 ["Code": 00, "Desc": success, "iinData": <__NSArrayM 0x1c0253

我想将来自web服务的JSON结果保存到核心数据,下面是JSON解析的代码

if let jsonResult = try JSONSerialization.jsonObject(with: JSONData!, options: [.mutableContainers]) as? [String: AnyObject]
如果我打印jsonResult,下面是输出

["Code": 00, "Desc": success, "iinData": <__NSArrayM 0x1c02531a0>
{
  name = “AAA”;
  iin = 123456;
  isOn = 0;
},
{
  name = "Allahabad Bank";
  iin = 608112;
  isOn = 0;
},
)

使用
Decodable

  • 首先,创建
    codingUserInfo-Key
    JSONDecoder
    的扩展,以便能够传递托管对象上下文

    extension CodingUserInfoKey {
        static let context = CodingUserInfoKey(rawValue: "context")!
    }
    
    extension JSONDecoder {
        convenience init(context: NSManagedObjectContext) {
            self.init()
            self.userInfo[.context] = context
        }
    }
    
  • 将一致性添加到两个类中的
    可解码

    class Name: NSManagedObject, Decodable {
    
    class ParamDownload: NSManagedObject, Decodable {
    
  • 在类
    Name
    (不是扩展名)中添加

  • 在类
    ParamDownload
    (不是扩展名)中添加

    init
    方法处理这些关系

    我建议尽可能多地声明核心数据属性-可选。

    如果某个属性必须保持可选,则将
    解码
    替换为
    解码当前

    ,这对我来说也很好

    private func createParamDownloadEntityFrom(dictionary: [String: AnyObject]) -> NSManagedObject? {
        let context = CoreDataStack.sharedInstance.persistentContainer.viewContext
    
        if let paramEntity = NSEntityDescription.insertNewObject(forEntityName: “ParamDwonload”, into: context) as? ParamDownload {
            paramEntity.code = dictionary[“code”] as? String
            paramEntity.desc = dictionary[“desc”] as? String
            let innData = dictionary["iinData"] as! NSArray
    
    
            for i in 0..<(innData.count-1) {
    
                if let nameEntity = NSEntityDescription.insertNewObject(forEntityName: Name
                    , into: context) as? Name {
    
                    if let val = innData[i] as? [String: Any] {
                        nameEntity.bankName = val[“name"] as? String
                        nameEntity.iin = val[“iin"] as? String
                        if let isOn = Int16(val[“isOn"] as! String) {
                            nameEntity.isOnus = isOn
                        }
                        paramEntity.addToNames(nameEntity)
                    }
    
                }
            }
            return paramEntity
        }
    
    private func createParamDownloadEntityFrom(字典:[字符串:AnyObject])->NSManagedObject?{
    让context=CoreDataStack.sharedInstance.persistentContainer.viewContext
    如果让paramEntity=NSEntityDescription.insertNewObject(forEntityName:“ParamdOnLoad”,into:context)作为?ParamDownload{
    parametity.code=字典[“code”]作为字符串
    parametity.desc=字典[“desc”]作为字符串
    让innData=dictionary[“iInnda”]作为!NSArray
    
    对于0中的i..我通过将JSON转换为数据并将该数据保存在CoreData中来保存JSON

    以下代码适用于我

    func saveSpotsLocation(model: SpotsModel, packageId: String, regionName: String) {
      let newUser = NSEntityDescription.insertNewObject(forEntityName: "SpotsDetail", into: context)
      do {
        let data = NSKeyedArchiver.archivedData(withRootObject: model.dictionaryRepresentation())
        newUser.setValue(data, forKey: "data")
        newUser.setValue(packageId, forKey: "packageId")
        newUser.setValue(regionName, forKey: "regionName")
        try context.save()
      } catch {
        print("failure")
      }
    }
    

    使用convert to data?Nskeyedarchieve?您是如何将解析后的JSON保存到CoreData的?您似乎只使用了
    JSONSerialization
    进行解码,但没有将数据转换为您创建的CoreData格式。谢谢或您的回复。我更新了将数据插入entity1的代码。您能否解释一下如何插入将数据导入Entity2。因为这是一对多关系数据。感谢您的回复。只需做一些更改,即可正常工作。
    private enum CodingKeys: String, CodingKey { case code = "Code", desc = "Desc", names = "iinData" }
    
    required convenience init(from decoder: Decoder) throws {
        guard let context = decoder.userInfo[.context] as? NSManagedObjectContext else { fatalError("NSManagedObjectContext is missing") }
        let entity = NSEntityDescription.entity(forEntityName: "ParamDownload", in: context)!
        self.init(entity: entity, insertInto: context)
        let values = try decoder.container(keyedBy: CodingKeys.self)
        code = try values.decode(String.self, forKey: .code)
        desc = try values.decode(String.self, forKey: .desc)
        names = try values.decode(Set<Name>.self, forKey: .names)
        names.forEach { $0.pd = self }
    }
    
    let decoder = JSONDecoder(context: CoreDataStack.sharedInstance.persistentContainer.viewContext)
    
    private func createParamDownloadEntityFrom(dictionary: [String: AnyObject]) -> NSManagedObject? {
        let context = CoreDataStack.sharedInstance.persistentContainer.viewContext
    
        if let paramEntity = NSEntityDescription.insertNewObject(forEntityName: “ParamDwonload”, into: context) as? ParamDownload {
            paramEntity.code = dictionary[“code”] as? String
            paramEntity.desc = dictionary[“desc”] as? String
            let innData = dictionary["iinData"] as! NSArray
    
    
            for i in 0..<(innData.count-1) {
    
                if let nameEntity = NSEntityDescription.insertNewObject(forEntityName: Name
                    , into: context) as? Name {
    
                    if let val = innData[i] as? [String: Any] {
                        nameEntity.bankName = val[“name"] as? String
                        nameEntity.iin = val[“iin"] as? String
                        if let isOn = Int16(val[“isOn"] as! String) {
                            nameEntity.isOnus = isOn
                        }
                        paramEntity.addToNames(nameEntity)
                    }
    
                }
            }
            return paramEntity
        }
    
    func saveSpotsLocation(model: SpotsModel, packageId: String, regionName: String) {
      let newUser = NSEntityDescription.insertNewObject(forEntityName: "SpotsDetail", into: context)
      do {
        let data = NSKeyedArchiver.archivedData(withRootObject: model.dictionaryRepresentation())
        newUser.setValue(data, forKey: "data")
        newUser.setValue(packageId, forKey: "packageId")
        newUser.setValue(regionName, forKey: "regionName")
        try context.save()
      } catch {
        print("failure")
      }
    }