My app uses core data, which stores instances of a custom class CustomClass.
This class has a number of properties, most of them of standard types, but one property is xxx: Set<CustomObject>.
The xcdatamodeld thus specifies (among the others with standard types) an attribute xxx of type Transformable. xxx is the Set<CustomObject>.
Its type is Optional and the Transformer is now NSSecureUnarchiveFromData.
Earlier the Transformer was not specified, and thus decoding was not secure. But Apple now advises to use secure coding, since insecure coding will be deprecated in future.
To enable secure coding, I did the following:
CustomClass now adopts NSSecureCoding instead of NSCoding.
The following var was added to CustomClass:
public static var supportsSecureCoding: Bool { get { return true } }
Then I tried to modify public required convenience init?(coder aDecoder: NSCoder) {…} so that attribute xxx is securely decoded. I know that instead of
let xxx = aDecoder.decodeObject(forKey: „xxx“) as? Set<CustomObject>
I have to use now decodeObject(of:forKey:), where of is the type of the object to be decoded, here type Set<CustomObject>.
My problem is that I don’t know how to formulate this: If I use
let xxx = aDecoder.decodeObject(of: Set<CustomObject>.self, forKey: „xxx“)
I get the error Cannot convert value of type 'Set<CustomObject>.Type' to expected argument type '[AnyClass]?' (aka 'Optional<Array<AnyObject.Type>>‘).
Apparently the compiler did not compile
func decodeObject<DecodedObjectType>(of cls: DecodedObjectType.Type, forKey key: String) -> DecodedObjectType? where DecodedObjectType : NSObject, DecodedObjectType : NSCoding
but instead
func decodeObject(of classes: [AnyClass]?, forKey key: String) -> Any?
i.e. it treated Set<CustomObject> not as a single type, but as a collection of types.
So, how do I specify that only a single type should be decoded, namely Set<CustomObject>?
Unfortunately, I could not find anything in the Apple docs, but I found a hint to the solution in this post:
NSSecureCodingis not available for all standard swift classes. For those classes, that don’t support it, one has to use the Objective-C counterpart classes, i.e.NSStringinstead ofString.One example: If
var string = "String"has to be securely encoded, one has to use e.g.aCoder.encode(string as NSString, forKey: „string“).Now currently
Setis not supported byNSSecureCoding. I had to use thusand