2017-04-26 16 views
0

我試圖捕獲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 
)}'.' 

推測這是剛纔那種例外的是NSKeyedUnarchiverDelegateunarchiver(_:cannotDecodeObjectOfClassName:originalClasses:)應該被調用,基於its documentation

通知代表具有給定名稱的類在解碼期間不可用。

但在我的情況下,該方法不與上述代碼段調用(即使其它委託方法,像unarchiverWillFinish(_:)unarchiver(_:didDecode:)通常調用時解碼不會遇到的問題。

不同於在原文中,我不能使用像decodeTopLevelObjectForKey這樣的類函數,在那裏我可以用try?來處理異常,因爲我需要支持使用NSSecureCoding協議的安全編碼和解碼,像討論的here一樣,這迫使我使用decodeObject(of:forKey),它不會拋出我可以處理的任何異常,並且,在拋出導致應用程序崩潰的運行時異常之前,它不會通知我的委託人。

實際調用委託方法unarchiver(_:cannotDecodeObjectOfClassName:originalClasses:)的場景是什麼?我如何聆聽並響應我的NSSecureCoding設置下的NSInvalidUnarchiveOperationException,以便在解碼不成功時避免運行時崩潰?

回答

相關問題