How to call decoder with the right types ?

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 ?

Answered by DTS Engineer in 873581022

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.

Accepted Answer

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.

How to call decoder with the right types ?
 
 
Q