在Swift中将复杂的JSON保存到核心数据 [英] Save complex JSON to Core Data in Swift
问题描述
我想将Web服务的JSON结果保存到Core数据,以下是JSON解析的代码。
I want to save the JSON Result from web service to Core data, following is the code for JSON parsing.
if let jsonResult = try JSONSerialization.jsonObject(with: JSONData!, options: [.mutableContainers]) as? [String: AnyObject]
如果我打印jsonResult,则输出为
If i prints jsonResult, following is the output
["Code": 00, "Desc": success, "iinData": <__NSArrayM 0x1c02531a0>
{
name = "AAA";
iin = 123456;
isOn = 0;
},
{
name = "Allahabad Bank";
iin = 608112;
isOn = 0;
},
)
我可以插入代码, Desc 进入Entity1,但如何将innData插入Entity2。
I can able to insert Code, Desc into Entity1, but how to insert innData into Entity2 .
Entity1结构 < a href = https://i.stack.imgur.com/FUW1b.png rel = nofollow noreferrer> Entity2结构
以下是将JSON结果插入核心数据的代码
Following is the code for inserting JSON result into core data
func createEntity1From(dictionary: [String: AnyObject]) -> NSManagedObject? {
let context = CoreDataStack.sharedInstance.persistentContainer.viewContext
if let Entity1 = NSEntityDescription.insertNewObject(forEntityName: "ParamDownload", into: context) as? ParamDownload {
Entity1.Code= dictionary["name"] as? String
Entity1.desc = dictionary["desc"] as? String
return Entity1
}
}
推荐答案
使用 Decodable
- $ b $将JSON直接解码为Core Data很容易b
-
首先创建
CodingUserInfoKey
和JSONDecoder
的扩展名,以便能够传递托管对象context
First of all create extensions of
CodingUserInfoKey
andJSONDecoder
to be able to pass the managed object context
extension CodingUserInfoKey {
static let context = CodingUserInfoKey(rawValue: "context")!
}
extension JSONDecoder {
convenience init(context: NSManagedObjectContext) {
self.init()
self.userInfo[.context] = context
}
}
为 Decodable
class Name: NSManagedObject, Decodable {
class ParamDownload: NSManagedObject, Decodable {
在类中
(不是扩展名)添加
private enum CodingKeys: String, CodingKey { case name, iin, isOn }
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: "Name", in: context)!
self.init(entity: entity, insertInto: context)
let values = try decoder.container(keyedBy: CodingKeys.self)
name = try values.decode(String.self, forKey: .name)
iin = try values.decode(String.self.self, forKey: .iin)
isOn = try values.decode(Bool.self.self, forKey: .isOn)
}
在类 ParamDownload
(不是扩展名)
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 }
}
要解码JSON,请使用便捷的初始化程序创建解码器
To decode the JSON create the Decoder with the convenience initializer
let decoder = JSONDecoder(context: CoreDataStack.sharedInstance.persistentContainer.viewContext)
init
处理关系的方法。
我建议声明Core Data属性,尽可能非-可选。
如果某个属性必须保留为可选属性,则将 decode
替换为 decodeIfPresent
。
I recommend to declare the Core Data attributes as much non-optional as possible.
If an attribute must be remain optional replace decode
with decodeIfPresent
.
这篇关于在Swift中将复杂的JSON保存到核心数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!