NSKeyedUnarchiver validateAllowedClass error

I get this error in Xcode 14 / iOS 16 on device that I had not with previous versions.

[general] *** -[NSKeyedUnarchiver validateAllowedClass:forKey:] allowed unarchiving safe plist type ''NSNumber' (0x205da88f8) [/System/Library/Frameworks/Foundation.framework]' for key 'NS.objects', even though it was not explicitly included in the client allowed classes set: '{(
    "'NSDictionary' (0x205da1178) [/System/Library/Frameworks/CoreFoundation.framework]",
    "'NSString' (0x205da8948) [/System/Library/Frameworks/Foundation.framework]"
)}'. This will be disallowed in the future.

The only places where I reference NSDictionary.self or NSString.self or NSNumber.self for allowed classes are:

@objc class MyClass : NSObject, NSSecureCoding {   
    required init(coder decoder: NSCoder) {
       let myObject = decoder.decodeObject(of: [MyClass.self, NSNumber.self, NSArray.self, NSDictionary.self, NSString.self], forKey: myKey) as? [SomeClass] ?? []
    }

and in another class

class Util {

// in a class func:
    let data = try Data(contentsOf: fileURL)
    guard let unarchived = try NSKeyedUnarchiver.unarchivedObject(ofClass: NSDictionary.self, from: data) else { return nil }

I do not understand what NS.objects refers to.

I tried to add NSObject.self in

       let myObject = decoder.decodeObject(of: [MyClass.self, NSNumber.self, NSArray.self, NSDictionary.self, NSString.self, NSObject.self], forKey: myKey) as? [SomeClass] ?? []

but that gave even more warnings:

[Foundation] *** -[NSKeyedUnarchiver validateAllowedClass:forKey:]: NSSecureCoding allowed classes list contains [NSObject class], which bypasses security by allowing any Objective-C class to be implicitly decoded. Consider reducing the scope of allowed classes during decoding by listing only the classes you expect to decode, or a more specific base class than NSObject. This will become an error in the future. Allowed class list: {(
    "'NSNumber' (0x205da88f8) [/System/Library/Frameworks/Foundation.framework]",
    "'NSArray' (0x205da1240) [/System/Library/Frameworks/CoreFoundation.framework]",
    "'NSObject' (0x205d8cb98) [/usr/lib]",
    "'NSDictionary' (0x205da1178) [/System/Library/Frameworks/CoreFoundation.framework]",
    "'MyClass.self' (0x1002f11a0) [/private/var/containers/Bundle/Application/5517240E-FB23-468D-80FA-B7E37D30936A/MyApp.app]",
    "'NSString' (0x205da8948) [/System/Library/Frameworks/Foundation.framework]"

Another warning refers to NS.keys:

2022-09-16 16:19:10.911977+0200 MyApp[4439:1970094] [general] *** -[NSKeyedUnarchiver validateAllowedClass:forKey:] allowed unarchiving safe plist type ''NSString' (0x205da8948) [/System/Library/Frameworks/Foundation.framework]' for key 'NS.keys', even though it was not explicitly included in the client allowed classes set: '{(
    "'NSDictionary' (0x205da1178) [/System/Library/Frameworks/CoreFoundation.framework]"
)}'. This will be disallowed in the future.

I do not understand what NS.keys refers to.

What additional class types should I add ?

Answered by RickMaddy in 728411022

When debugging a message such as:

[general] *** -[NSKeyedUnarchiver validateAllowedClass:forKey:] allowed unarchiving safe plist type ''NSNumber' (0x205da88f8) [/System/Library/Frameworks/Foundation.framework]' for key 'NS.objects', even though it was not explicitly included in the client allowed classes set: '{(
    "'NSDictionary' (0x205da1178) [/System/Library/Frameworks/CoreFoundation.framework]",
    "'NSString' (0x205da8948) [/System/Library/Frameworks/Foundation.framework]"
)}'. This will be disallowed in the future.

you want to look for a use of NSKeyedUnarchiver where you only list NSDictionary and NSString. Then you want to add NSNumber. Do not add NSObject.

If I understand correctly, NS.keys and NS.objects only reger to leys and values in plist.

The only types in the plist are Array, Dictionary, Bool, String and Number.

Accepted Answer

When debugging a message such as:

[general] *** -[NSKeyedUnarchiver validateAllowedClass:forKey:] allowed unarchiving safe plist type ''NSNumber' (0x205da88f8) [/System/Library/Frameworks/Foundation.framework]' for key 'NS.objects', even though it was not explicitly included in the client allowed classes set: '{(
    "'NSDictionary' (0x205da1178) [/System/Library/Frameworks/CoreFoundation.framework]",
    "'NSString' (0x205da8948) [/System/Library/Frameworks/Foundation.framework]"
)}'. This will be disallowed in the future.

you want to look for a use of NSKeyedUnarchiver where you only list NSDictionary and NSString. Then you want to add NSNumber. Do not add NSObject.

@RickMaddy Thanks for your help.

In Xcode 14 for iOS 16, I added NSNumber:

guard let unarchived = try NSKeyedUnarchiver.unarchivedObject(ofClasses: [NSDictionary.self, NSNumber.self], from: data) else {

No more crash.

The I reverted to the previous code… no crash either !!!

I'm really confused…

Problem solved.

What confused me is that it did not show in simulator, only on device.

So, I have changed as:

guard let unarchived = try NSKeyedUnarchiver.unarchivedObject(ofClasses: [NSDictionary.self, NSNumber.self, NSString.self], from: data) else {

and error cleared.

Thanks @RickMaddy 

NSKeyedUnarchiver validateAllowedClass error
 
 
Q