2017-04-26 21 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,以便在解码不成功时避免运行时崩溃?

回答

相关问题