Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS 15 warning: NSKeyedUnarchiver _warnAboutPlistType:missingInAllowedClasses:

Xcode 13 and iOS 15 began warning about missingAllowedClasses when using custom DataTransformers. There is very little documentation on custom DataTransformers, so I thought I would post a question and answer it here.

[general] *** -[NSKeyedUnarchiver _warnAboutPlistType:missingInAllowedClasses:] allowed unarchiving safe plist type ''NSString' (0x1dc9a7660) [/System/Library/Frameworks/Foundation.framework]', even though it was not explicitly included in the client allowed classes set: '{(
    "'NSArray' (0x1dc99c838) [/System/Library/Frameworks/CoreFoundation.framework]"
)}'. This will be disallowed in the future.

Notice in the warning message, it specifies 'NSArray' and the type missing, 'NSString'.

like image 716
Tom GODDARD Avatar asked Jun 28 '21 02:06

Tom GODDARD


2 Answers

I faced this issue for userDefaults while saving custom models, and I fixed it by passing classes of [NSArray.self, NSString.self,NSNumber.self,CustomModel.self] to silence this warning.

Note: before iOS 15 I just passed an NSArray class, but now I have to pass other classes like NSString or NSNumber because my custom model has strings, numbers and arrays.

{
  decodeData = try NSKeyedUnarchiver.unarchivedObject(
    ofClasses: [NSArray.self, NSString.self, NSNumber.self, CustomModel.self], from: customModel
  ) as? [CustomModel]
}
like image 113
fadi_rasheed Avatar answered Oct 21 '22 06:10

fadi_rasheed


Here is an array value transformer that received the new warning, but no longer does since NSString was added:

// 1. Subclass from `NSSecureUnarchiveFromDataTransformer`
@objc(ArrayValueTransformer)
final class ArrayValueTransformer: NSSecureUnarchiveFromDataTransformer {
    
    static let name = NSValueTransformerName(rawValue: String(describing: ArrayValueTransformer.self))

    // 2. Make sure `NSArray` is in the allowed class list. However, since the array can also contain strings, be sure to include NSString.self in the allowedTopLevelClasses
    override static var allowedTopLevelClasses: [AnyClass] {
        return [NSArray.self, NSString.self] // Added NSString.self here to fix warning
    }

    /// Registers the transformer.
    public static func register() {
        let transformer = ArrayValueTransformer()
        ValueTransformer.setValueTransformer(transformer, forName: name)
    }
}

You can also silence warnings if using: return try? NSKeyedUnarchiver.unarchivedObject(ofClasses:from:) by passing the same array that is specified in the return of allowedTopLevelClasses to the ofClasses parameter.

like image 40
Tom GODDARD Avatar answered Oct 21 '22 08:10

Tom GODDARD