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
Nasa
toPod
- Change Codegen to
Category/Extension
, and - Set module to current and save
import CoreData
NSManagedObject
- Delete properties in Pod
- Change
Codble
toDecodable
- Remove id
- add
DecoderConfigurationError
- add
CodingUserInfoKey
- add
convenience
- add
context
- add
self.init
- add
decoder.userInfo[CodingUserInfoKey.managedObjectContext] = PersistenceController.shared.container.viewContext
- add
if let
to 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)