I have defined a class :
class Item: NSObject, NSSecureCoding {
var name : String = ""
var color : ColorTag = .black // defined as enum ColorTag: Int
var value : Int = 0
static var supportsSecureCoding: Bool {
return true
}
Its decoder includes the following print statement to start:
required init(coder decoder: NSCoder) {
print(#function, "item should not be nil", decoder.decodeObject(of: Item.self, forKey: someKey))
Another class uses it:
class AllItems: NSObject, NSSecureCoding {
var allItems : [Item]?
static var supportsSecureCoding: Bool {
return true
}
and decodes as follows
required init(coder decoder: NSCoder) {
super.init() // Not sure it is necessary
allItems = decoder.decodeObject(of: NSArray.self, forKey: mykey) as? [Item]
print(#function, allItems) // <<-- get nil
}
I note:
- decoder returns nil at line 5
- I have tried to change to
decoder.decodeObject(of: [NSArray.self, NSString.self, NSColor.self, NSNumber.self], forKey: mykey))
- Still get nil
- And, decoder of class Item is not called (no print in the log)
What am I missing ?
NSSecureCoding requires explicit type declaration for all classes in the object graph. When decoding an array, you must specify both the container type (NSArray) AND the element type (Item). The current code only specifies NSArray.self or Item.self (but not both), so the decoder doesn't know it's allowed to decode the Item objects from the array. You tried [NSArray.self, NSString.self, NSColor.self, NSNumber.self], but didn't include Item.self in the list. Other than that, verify both classes have complete encode/decode pairs using the same keys in both the encoding and decoding methods. Make sure all the key strings match exactly, etc.