Reputation: 1
Need to save my big custom struct in Core Data, but ValueTransformer
can't archive data and I get error:
"Error Domain=NSCocoaErrorDomain Code=4866 "The data couldn’t be written because it isn’t in the correct format." UserInfo={NSUnderlyingError=0x600002d70ba0 {Error Domain=NSCocoaErrorDomain Code=4864 "This decoder will only decode classes that adopt NSSecureCoding. Class '__SwiftValue' does not adopt it." UserInfo={NSDebugDescription=This decoder will only decode classes that adopt NSSecureCoding. Class '__SwiftValue' does not adopt it.}}}"
Below my ValueTransformer
class and model which I want to save
class MyValueTransformer: ValueTransformer {
override func transformedValue(_ value: Any?) -> Any? {
guard let model = value as? CoreDataModel else { print("HUI"); return nil }
do {
let data = try NSKeyedArchiver.archivedData(withRootObject: model, requiringSecureCoding: true)
print("value transformer do")
return data
} catch {
print(error) // Catch this error which i describe higher
print("value transformer catch")
return nil
}
}
MODEL:
Model's rows:
Upvotes: 0
Views: 1122
Reputation: 13980
What the error tells you is that NSSecureCoding
, which is used by NSKeyedArchiver
does not support Swift struct
. It can only work with classes that inherit from NSObject
(note the NS*
preefix - any time you see it, you are on Objective-C land), i.e.:
class X: NSObject { }
Conforming to Codable
is not going to help.
So you have 2 options:
Convert your struct
s to class
es and get them to inherit from NSObject
, as well as NSCoding
or NSSecureCoding
. This is the simpler option.
Leave original structures intact, but create their corresponding helper classes that do implement NSObject
and NSCoding
or NSSecureCoding
. This solution is described here
Note that you will also have trouble with enum PurpleType: String
with NSCoding, as (as enums can only be Int
in Objective-C land)
Upvotes: 2