Swift define standard approach to data encoding and decoding which combines the Encodable and Decodable protocols that is called Codable.
In this block I illustrated Codable using API parse and store into CoreData.
First you need to create entity called "List" and create attribute(id,user_id,title,body) like below
and then create NSManageObject subclass for List entity.
Now create encode and decode method like below
In this block I illustrated Codable using API parse and store into CoreData.
First you need to create entity called "List" and create attribute(id,user_id,title,body) like below
List Entity |
and then create NSManageObject subclass for List entity.
Now create encode and decode method like below
import Foundation
import CoreData
@objc(List)
public class List: NSManagedObject,Codable {
///From api response key if changed
enum apiKey: String, CodingKey {
case id
case user_id = "userId"
case title
case body
}
// MARK: - Decodable
required convenience public init(from decoder: Decoder) throws {
///Fetch context for codable
guard let codableContext = CodingUserInfoKey.init(rawValue: "context"),
let manageObjContext = decoder.userInfo[codableContext] as? NSManagedObjectContext,
let manageObjList = NSEntityDescription.entity(forEntityName: "List", in: manageObjContext) else {
fatalError("failed")
}
self.init(entity: manageObjList, insertInto: manageObjContext)
let container = try decoder.container(keyedBy: apiKey.self)
self.user_id = try container.decodeIfPresent(Int64.self, forKey: .user_id) ?? 0
self.id = try container.decodeIfPresent(Int64.self, forKey: .id) ?? 0
self.title = try container.decodeIfPresent(String.self, forKey: .title)
self.body = try container.decodeIfPresent(String.self, forKey: .body)
}
// MARK: - encode
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: apiKey.self)
try container.encode(user_id, forKey: .user_id)
try container.encode(id, forKey: .id)
try container.encode(title, forKey: .title)
try container.encode(body, forKey: .body)
}
}
Now send server request and parse response using Codable and store into CoreData.
///get data from api
func getListData() {
guard let listURL = URL(string: "https://jsonplaceholder.typicode.com/posts/")else {
return
}
URLSession.shared.dataTask(with: listURL){
(data,response,error) in
guard let jsonData = data else { return }
DispatchQueue.main.async {
self.parseResponse(forData: jsonData)
}
}.resume()
}
///parse response using decodable and store data
func parseResponse(forData jsonData : Data) {
do {
guard let codableContext = CodingUserInfoKey.init(rawValue: "context") else {
fatalError("Failed context")
}
let manageObjContext = appDelegate.persistentContainer.viewContext
let decoder = JSONDecoder()
decoder.userInfo[codableContext] = manageObjContext
// Parse JSON data
_ = try decoder.decode([List].self, from: jsonData)
///context save
try manageObjContext.save()
UserDefaults.standard.set(true, forKey: "isAllreadyFetch")
self.fetchLocalData()
} catch let error {
print("Error ->\(error.localizedDescription)")
self.errorMessage(error.localizedDescription)
}
}
And fetch data like below
///Local data fetch from core data
func fetchLocalData() {
let manageObjContext = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<List>(entityName: "List")
///Sort by id
let sortDescriptor = NSSortDescriptor(key: "id", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor]
do {
self.arrayOfList = try manageObjContext.fetch(fetchRequest)
} catch let error {
print(error)
self.errorMessage(error.localizedDescription)
}
}
The sample code for illustrated in this post is available on GitHub.
Thank you.
No comments:
Post a Comment