Skip to content

Instantly share code, notes, and snippets.

@AlexZverusha
Forked from Akhu/CoreData + Codable.swift
Created November 6, 2020 14:58
Show Gist options
  • Save AlexZverusha/ad9f571d953bbf510b39fec2b322ab30 to your computer and use it in GitHub Desktop.
Save AlexZverusha/ad9f571d953bbf510b39fec2b322ab30 to your computer and use it in GitHub Desktop.
Mixing Codable and Core Data in Swift
//
// Article.swift
// Veille
//
// Created by Anthony Da Cruz on 26/01/2018.
// Copyright © 2018 Anthony Da Cruz. All rights reserved.
//
import Foundation
import CoreData
class Article: NSManagedObject, Decodable {
@NSManaged var title:String!
@NSManaged var summary:String?
@NSManaged var link:URL!
@NSManaged var image:URL?
@NSManaged var createdDate: Date
//var tags:[String]?
@NSManaged var id:UUID
enum CodingKeys: String, CodingKey {
case title
case summary = "description"
case link
case image = "imageURL"
case createdDate = "date"
}
required convenience init(from decoder: Decoder) throws {
guard let contextUserInfoKey = CodingUserInfoKey.context else { fatalError("cannot find context key") }
guard let managedObjectContext = decoder.userInfo[contextUserInfoKey] as? NSManagedObjectContext else { fatalError("cannot Retrieve context") }
guard let entity = NSEntityDescription.entity(forEntityName: "Article", in: managedObjectContext) else { fatalError() }
self.init(entity: entity, insertInto: nil)
let values = try decoder.container(keyedBy: CodingKeys.self)
self.createdDate = Date()
self.title = try values.decode(String.self, forKey: .title)
self.summary = try values.decode(String.self, forKey: .summary)
guard let linkString = try values.decodeIfPresent(String.self, forKey: .link) else { return }
if let linkUrl = URL(string: linkString) {
self.link = linkUrl
}
if let imageURLString = try values.decodeIfPresent(String.self, forKey: .image) {
if let imageURL = URL(string: imageURLString){
self.image = imageURL
}
}
}
}
extension Article: Encodable{
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(self.title, forKey: .title)
try container.encodeIfPresent(self.summary, forKey: .summary)
try container.encodeIfPresent(self.image, forKey: .image)
try container.encode(self.link, forKey: .link)
try container.encode(self.createdDate.toIso8601(), forKey: .createdDate)
}
}
extension CodingUserInfoKey {
static let context = CodingUserInfoKey(rawValue: "context")
}
// Use it :
let context = CoreDataStack.store.persistentContainer.newBackgroundContext() //Getting context
let plistDecoderForArticle = PropertyListDecoder()
plistDecoderForArticle.userInfo[CodingUserInfoKey.context!] = context //Pass it to CodingUserInfoKey which is made for that
let decodedData = try plistDecoderForArticle.decode([Article].self, from: data) //Decoding init got the managedObjectContext
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment