SpacePod 32 CoreData Decodable NSManagedObject
Previously we added a CoreData model named Nasa. Let’s rename it to Pod to mirror our existing object, and then work through the resulting build errors so that our app is using the new object.
Goals
- Mirror CoreData Model and Pod Model
- Update Pod to work with CoreData
- Update our views to ensure everything still works as before
Steps
- Rename
NasatoPod - Change Codegen to
Category/Extension, and - Set module to current and save
import CoreDataNSManagedObject- Delete properties in Pod
- Change
CodbletoDecodable - Remove id
- add
DecoderConfigurationError - add
CodingUserInfoKey - add
convenience - add
context - add
self.init - add
decoder.userInfo[CodingUserInfoKey.managedObjectContext] = PersistenceController.shared.container.viewContext - add
if letto optionals in views
Steps
1, 2, 3
<entity name="Pod" representedClassName=".Pod" syncable="YES" codeGenerationType="category">
4 to 13, Pod.swift Complete
import Foundation
import CoreData
class Pod: NSManagedObject, Decodable {
private enum CodingKeys: String, CodingKey {
case copyright
case date
case explanation
case hdurl
case mediaType
case serviceVersion
case title
case url
case thumbnailUrl
}
enum DecoderConfigurationError: Error {
case missingManagedObjectContext
}
required convenience init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
guard let context = decoder.userInfo[CodingUserInfoKey.managedObjectText] as? NSManagedObjectContext else {
throw DecoderConfigurationError.missingManagedObjectContext
}
self.init(context: context)
copyright = try container.decodeIfPresent(String.self, forKey: .copyright)
date = try container.decodeIfPresent(Date.self, forKey: .date)
explanation = try container.decode(String.self, forKey: .explanation)
hdurl = try container.decodeIfPresent(URL.self, forKey: .hdurl)
mediaType = try container.decode(String.self, forKey: .mediaType)
serviceVersion = try container.decode(String.self, forKey: .serviceVersion)
title = try container.decode(String.self, forKey: .title)
url = try container.decodeIfPresent(URL.self, forKey: .url)
thumbnailUrl = try container.decodeIfPresent(URL.self, forKey: .thumbnailUrl)
}
}
extension CodingUserInfoKey {
static let managedObjectText = CodingUserInfoKey(rawValue: "managedObjectContext")!
}
14 Data+Extensions.swift
decoder.userInfo[CodingUserInfoKey.managedObjectContext] = PersistenceController.shared.container.viewContext
15 Optionals
Handle optionals in our views with if let... (for now)