我試圖捕獲NSKeyedUnarchiver
取消存檔異常NSInvalidUnarchiveOperationException
,其中未知類正在通過NSSecureCoding
協議安全解碼。``cannotDecodeObjectOfClassName``不在'NSKeyedArchiverDelegate`中調用
我使用的解決方案基於相關的NSKeyedUnarchiverDelegate SO post,通過實施代理協議NSKeyedUnarchiverDelegate
,因此我可以通過unarchiver(_:cannotDecodeObjectOfClassName:originalClasses:)
收聽和迴應異常。但是,在解碼過程中遇到未知類時,該委託方法似乎不會被調用。
下面是我用於安全地取消存檔數組對象的代碼片段。
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
在原始NSKeyedUnarchiverDelegate SO post實現就像我指了指。在我的設置,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:
通知代表具有給定名稱的類在解碼期間不可用。
但在我的情況下,該方法不與上述代碼段調用(即使其它委託方法,像unarchiverWillFinish(_:)
或unarchiver(_:didDecode:)
通常調用時解碼不會遇到的問題。
不同於在原文中,我不能使用像decodeTopLevelObjectForKey
這樣的類函數,在那裏我可以用try?
來處理異常,因爲我需要支持使用NSSecureCoding
協議的安全編碼和解碼,像討論的here一樣,這迫使我使用decodeObject(of:forKey)
,它不會拋出我可以處理的任何異常,並且,在拋出導致應用程序崩潰的運行時異常之前,它不會通知我的委託人。
實際調用委託方法unarchiver(_:cannotDecodeObjectOfClassName:originalClasses:)
的場景是什麼?我如何聆聽並響應我的NSSecureCoding
設置下的NSInvalidUnarchiveOperationException
,以便在解碼不成功時避免運行時崩潰?