【发布时间】: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