【问题标题】:Xcode 13 Warning - [NSKeyedUnarchiver validateAllowedClass:forKey:]Xcode 13 警告 - [NSKeyedUnarchiver validateAllowedClass:forKey:]
【发布时间】:2021-11-20 21:44:56
【问题描述】:

我正在使用文件存储系统来保存一些符合可编码协议的数据模型。

我的保存功能如下:

func save<T: Encodable>(value: T, for key: String, on path: URL) throws {
        let url = path.appendingPathComponent(key, isDirectory: false)
        do {
            try ANFileManager.createDirectoryAtPath(path: url.deletingLastPathComponent())
            let archiver = NSKeyedArchiver(requiringSecureCoding: true)
            archiver.outputFormat = .binary
            try archiver.encodeEncodable(value, forKey: NSKeyedArchiveRootObjectKey)
            archiver.finishEncoding()
            // then you can use encoded data
            try archiver.encodedData.write(to: url)
            
        } catch {
            throw StorageError.cantWrite(error)
        }
    }

我的获取函数如下:

 func fetchValue<T: Decodable>(for key: String, from path: URL) throws -> T {
        let url = path.appendingPathComponent(key)
        
        let data = try Data(contentsOf: url)
        let unarchiver = try NSKeyedUnarchiver(forReadingFrom: data)
        unarchiver.decodingFailurePolicy = .setErrorAndReturn
        guard let decoded = unarchiver.decodeDecodable(T.self, forKey:
            NSKeyedArchiveRootObjectKey) else {
                throw StorageError.notFound
        }
        
        unarchiver.finishDecoding()
        
        if let error = unarchiver.error {
            throw StorageError.cantRead(error)
        }
        else {
            return decoded
        }
        
    }

保存和获取工作正常,但在运行时在 xcode 控制台中看到以下警告。

    *** -[NSKeyedUnarchiver validateAllowedClass:forKey:] allowed unarchiving safe plist type ''NSString' (0x7fff863014d0) [/Applications/Xcode_13.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks/Foundation.framework]' for key 'NS.keys', even though it was not explicitly included in the client allowed classes set: '{(
    "'NSDictionary' (0x7fff862db9a0) [/Applications/Xcode_13.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks/CoreFoundation.framework]",
    "'NSDate' (0x7fff862db798) [/Applications/Xcode_13.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks/CoreFoundation.framework]"
)}'. This will be disallowed in the future.

应该怎么做才能抑制警告?

【问题讨论】:

  • 可能有人会问,当 Codable 可以如此简单地直接保存为属性列表或 json 时,为什么要花这么多精力通过 NSKeyedUnarchiver?
  • 一开始想保存不可读文本的文件。
  • 另外,我的模型从 NSCoding 迁移到 Codable。
  • 对不起,这太荒谬了。 keyed archiver 和 Codable 属性列表的编码是相同的。你正在做的事情没有什么比“可读性”更差的了。而且它们现在是可编码的,那么为什么要活在过去呢?
  • 好的,我明白了。我将 KeyArchiver 用于我的模型确认到 NSCoding。并在将模型转换为可编码后继续使用相同的存储功能。我想我现在应该改变它。

标签: ios15 nskeyedunarchiver xcode13


【解决方案1】:

问题是无法在 unarchiver 上要求安全编码:

https://developer.apple.com/documentation/foundation/nskeyedunarchiver/1410824-requiressecurecoding

但更广泛地说,当 Codable 已经直接野蛮地通过键控存档时,这是非常奇怪的。

【讨论】:

  • unarchiver.requiresSecureCoding = false,添加了这个但仍然看到相同的警告。
  • 因为它必须是真的!
  • 我尝试删除所有与 Keyed archiver 相关的代码,但应用程序仍然看到此警告。我认为这是 firebase 库的问题,因为删除 Firebase 初始化似乎会删除警告。
猜你喜欢
  • 2021-11-10
  • 1970-01-01
  • 2021-09-10
  • 1970-01-01
  • 2020-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-14
相关资源
最近更新 更多