`cannotDecodeObjectOfClassName` 未在 `NSKeyedArchiverDelegate` 中调用
`cannotDecodeObjectOfClassName` not invoked in `NSKeyedArchiverDelegate`
我正在尝试捕获 NSKeyedUnarchiver
解压缩异常 NSInvalidUnarchiveOperationException
,其中一个未知的 class 正在通过 NSSecureCoding
协议安全解码。
我正在使用的解决方案是基于相关的 通过实现委托协议 NSKeyedUnarchiverDelegate
所以我可以通过 unarchiver(_:cannotDecodeObjectOfClassName:originalClasses:)
监听和响应异常。但是,在解码过程中遇到未知class时,似乎不会调用此委托方法。
这是我用于安全地取消归档数组对象的代码片段。
func securelyUnarchiveArrayOfCustomObject(from url: URL, for key: String) -> [MyCustomClass]? {
guard let data = try? Data(contentsOf: url) else {
os_log("Unable to locate data at given url.path: %@", log: OSLog.default, type: .error, url.path)
return nil
}
let unarchiver = NSKeyedUnarchiver(forReadingWith: data)
let delegate = UnarchiverDelegate() // Prevents `NSInvalidUnarchiveOperationException` crash
unarchiver.delegate = delegate
unarchiver.requiresSecureCoding = true // Prevents object substitution attack
let allowedClasses = [NSArray.self] // Will decode without problem if using [NSArray.self, MyCustomClass.self]
let decodedObject = unarchiver.decodeObject(of: allowedClasses, forKey: key)
let images = decodedObject as! [ImageWithCaption]?
unarchiver.finishDecoding()
return images
}
我的 UnarchiverDelegate
的实现就像我指出的原始 中一样。在我的设置下,decodeObject(of: allowedClasses, forKey: key)
不会抛出异常,而是引发运行时异常:
'NSInvalidUnarchiveOperationException', reason:
'value for key 'NS.objects' was of unexpected class
'MyCustomClassProject.MyCustomClass'. Allowed classes are '{(
NSArray
)}'.'
这应该只是 NSKeyedUnarchiverDelegate
的 unarchiver(_:cannotDecodeObjectOfClassName:originalClasses:)
应该被调用的那种异常,基于 its documentation:
Informs the delegate that the class with a given name is not available during decoding.
但在我的例子中,这个方法没有被上面的代码片段调用(即使其他委托方法,如 unarchiverWillFinish(_:)
或 unarchiver(_:didDecode:)
在解码没有遇到问题时被正常调用.
不像原来的post,我不能像decodeTopLevelObjectForKey
一样使用class函数,我可以用try?
处理异常,因为我需要支持使用 NSSecureCoding
协议的安全编码和解码, 如所讨论的 here。这迫使我使用 decodeObject(of:forKey)
,它不会抛出任何我可以处理的异常,而且,在抛出导致应用程序崩溃的运行时异常之前,它也不会通知我的委托。
委托方法unarchiver(_:cannotDecodeObjectOfClassName:originalClasses:)
在什么场景下才真正被调用?我如何在 NSSecureCoding
设置下收听 NSInvalidUnarchiveOperationException
并做出反应,以便在解码不成功时避免运行时崩溃?
有人在 Apple Dev Forum 上帮助了我。详情见:
我正在尝试捕获 NSKeyedUnarchiver
解压缩异常 NSInvalidUnarchiveOperationException
,其中一个未知的 class 正在通过 NSSecureCoding
协议安全解码。
我正在使用的解决方案是基于相关的 NSKeyedUnarchiverDelegate
所以我可以通过 unarchiver(_:cannotDecodeObjectOfClassName:originalClasses:)
监听和响应异常。但是,在解码过程中遇到未知class时,似乎不会调用此委托方法。
这是我用于安全地取消归档数组对象的代码片段。
func securelyUnarchiveArrayOfCustomObject(from url: URL, for key: String) -> [MyCustomClass]? {
guard let data = try? Data(contentsOf: url) else {
os_log("Unable to locate data at given url.path: %@", log: OSLog.default, type: .error, url.path)
return nil
}
let unarchiver = NSKeyedUnarchiver(forReadingWith: data)
let delegate = UnarchiverDelegate() // Prevents `NSInvalidUnarchiveOperationException` crash
unarchiver.delegate = delegate
unarchiver.requiresSecureCoding = true // Prevents object substitution attack
let allowedClasses = [NSArray.self] // Will decode without problem if using [NSArray.self, MyCustomClass.self]
let decodedObject = unarchiver.decodeObject(of: allowedClasses, forKey: key)
let images = decodedObject as! [ImageWithCaption]?
unarchiver.finishDecoding()
return images
}
我的 UnarchiverDelegate
的实现就像我指出的原始 decodeObject(of: allowedClasses, forKey: key)
不会抛出异常,而是引发运行时异常:
'NSInvalidUnarchiveOperationException', reason:
'value for key 'NS.objects' was of unexpected class
'MyCustomClassProject.MyCustomClass'. Allowed classes are '{(
NSArray
)}'.'
这应该只是 NSKeyedUnarchiverDelegate
的 unarchiver(_:cannotDecodeObjectOfClassName:originalClasses:)
应该被调用的那种异常,基于 its documentation:
Informs the delegate that the class with a given name is not available during decoding.
但在我的例子中,这个方法没有被上面的代码片段调用(即使其他委托方法,如 unarchiverWillFinish(_:)
或 unarchiver(_:didDecode:)
在解码没有遇到问题时被正常调用.
不像原来的post,我不能像decodeTopLevelObjectForKey
一样使用class函数,我可以用try?
处理异常,因为我需要支持使用 NSSecureCoding
协议的安全编码和解码, 如所讨论的 here。这迫使我使用 decodeObject(of:forKey)
,它不会抛出任何我可以处理的异常,而且,在抛出导致应用程序崩溃的运行时异常之前,它也不会通知我的委托。
委托方法unarchiver(_:cannotDecodeObjectOfClassName:originalClasses:)
在什么场景下才真正被调用?我如何在 NSSecureCoding
设置下收听 NSInvalidUnarchiveOperationException
并做出反应,以便在解码不成功时避免运行时崩溃?
有人在 Apple Dev Forum 上帮助了我。详情见: