iOS 15 警告:NSKeyedUnarchiver _warnAboutPlistType:missingInAllowedClasses:

Tom*_*ARD 23 xcode foundation ios swift cloudkit

使用自定义 DataTransformers 时,Xcode 13 和 iOS 15 开始发出关于 MissingAllowedClasses 的警告。关于自定义 DataTransformers 的文档非常少,所以我想我应该在这里发布一个问题并回答它。

[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.
Run Code Online (Sandbox Code Playgroud)

请注意,在警告消息中,它指定了“NSArray”,并且缺少类型“NSString”。

小智 15

userDefaults在保存自定义模型时遇到了这个问题,我通过传递类来[NSArray.self, NSString.self,NSNumber.self,CustomModel.self]消除此警告来修复它。

注意:在 iOS 15 之前,我只传递了一个NSArray类,但现在我必须传递其他类,例如NSStringor NSNumber,因为我的自定义模型有字符串、数字和数组。

{
  decodeData = try NSKeyedUnarchiver.unarchivedObject(
    ofClasses: [NSArray.self, NSString.self, NSNumber.self, CustomModel.self], from: customModel
  ) as? [CustomModel]
}
Run Code Online (Sandbox Code Playgroud)


Tom*_*ARD 2

这是一个数组值转换器,它收到了新的警告,但自从添加了 NSString 后就不再收到了:

// 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)
    }
}
Run Code Online (Sandbox Code Playgroud)

如果使用以下方法,您还可以使警告静音: return try? NSKeyedUnarchiver.unarchivedObject(ofClasses:from:)通过将返回值中指定的相同数组传递allowedTopLevelClassesofClasses参数。