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(wi
It's quite easy to decode the JSON directly into Core Data with Decodable
First of all create extensions of CodingUserInfoKey
and JSONDecoder
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
}
}
Add conformance to Decodable
in both classes
class Name: NSManagedObject, Decodable {
class ParamDownload: NSManagedObject, Decodable {
In the class Name
(not the extension) add
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)
}
In the class ParamDownload
(not the extension) add
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 }
}
To decode the JSON create the Decoder with the convenience initializer
let decoder = JSONDecoder(context: CoreDataStack.sharedInstance.persistentContainer.viewContext)
the init
methods handle the relationships.
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
.
This also worked fine for me,
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
}
I save JSON by converting it in into Data and save that Data in CoreData
Following Code works for me......
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")
}
}