I have an app that heavily uses Measurements. It is written in SwiftUI/iOS 14. I persist the data in a Core Data database. The app is working fine, until I try to implement secure coding. I made a sample app to strip everything away except the basics. It is based off of Xcode's default Core Data app with few changes. Again, I can save my measurement fine until I try to use secure coding.
The xddatamodel
, as well as the errors, is as follows:
I am using a manual codegen for the Entity and it looks like this:
extension Item {
@nonobjc public class func fetchRequest() -> NSFetchRequest<Item> {
return NSFetchRequest<Item>(entityName: "Item")
}
@NSManaged public var timestamp_: Date?
@NSManaged private var notes_: String?
@NSManaged private var length_: Measurement<UnitLength>?
public var timestamp: Date {
get { timestamp_ ?? Date(timeIntervalSince1970: 0) }
set { timestamp_ = newValue }
}
public var notes: String {
get { notes_ ?? "Add Notes Here..." }
set { notes_ = newValue }
}
public var length: Measurement<UnitLength> {
get { length_ ?? Measurement(value: 0, unit: UnitLength.meters) }
set { length_ = newValue }
}
}
While I have tried registering the ValueTransformer in different places, I currently have it in the @main:
@main
struct Core_Data_TestApp: App {
let persistenceController: PersistenceController
init() {
UnitLengthValueTransformer.register()
persistenceController = PersistenceController.shared
}
var body: some Scene {
WindowGroup {
ContentView()
.environment(\.managedObjectContext, persistenceController.container.viewContext)
}
}
}
My ValueTransformer looks like this:
@objc(UnitLengthValueTransformer)
final class UnitLengthValueTransformer: NSSecureUnarchiveFromDataTransformer {
static let name = NSValueTransformerName(rawValue: String(describing: UnitLengthValueTransformer.self))
override static var allowedTopLevelClasses: [AnyClass] {
return [UnitLength.self]
}
public static func register() {
let transformer = UnitLengthValueTransformer()
ValueTransformer.setValueTransformer(transformer, forName: name)
}
}
As I know there has been disagreement, the class header for UnitLength is:
open class UnitLength : Dimension, NSSecureCoding
so it does conform to NSSecureCoding.
I have used the following references:
Transformable and NSKeyedUnarchiveFromData
CoreData Transformable and NSSecureCoding in iOS 13+
ValueTransformer in Core Data explained: Storing absolute URLs
and I still get the same errors:
Fatal error: Unresolved error Error Domain=NSCocoaErrorDomain Code=134060 "A Core Data error occurred.", [:]: file Core_Data_Test/ContentView.swift, line 57
I can't figure out what I am doing wrong that is causing the crash.