How to save custom struct in Core Data?

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:

enter image description here

Model's rows:

enter image description here

Upvotes: 0

Views: 1122

Answers (1)

timbre timbre
timbre timbre

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:

  1. Convert your structs to classes and get them to inherit from NSObject, as well as NSCoding or NSSecureCoding. This is the simpler option.

  2. 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

Related Questions