skip to Main Content

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’.

2

Answers


  1. Chosen as BEST ANSWER

    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.


  2. 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]
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search