NSSecureCoding
プロトコルで未知のクラスが安全に解読されているので、NSKeyedUnarchiver
のアーカイブ解除例外をキャッチしようとしています。`NSKeyedArchiverDelegate`で` cannotDecodeObjectOfClassName`が呼び出されていません
デリゲートプロトコルNSKeyedUnarchiverDelegate
を実装して私が使用している解決策は、NSKeyedUnarchiverDelegate SO postに基づいていますので、私は聞き取り、unarchiver(_:cannotDecodeObjectOfClassName:originalClasses:)
で例外に応答することができます。ただし、このデリゲートメソッドは、デコード中に不明なクラスが検出された場合には呼び出されないようです。
ここでは、配列オブジェクトを安全にアーカイブ解除するために使用するコードスニペットを示します。私UnarchiverDelegate
はちょうど私が指さ元NSKeyedUnarchiverDelegate SO postのように実装されている
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
}
。私の設定の下では、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:)
のような他のデリゲートメソッドは、正常に起動されていても(上記のスニペットで呼び出されていません。
とは異なり、元の投稿では、私はtry?
で例外を処理することができるdecodeTopLevelObjectForKey
のようなクラス機能を使用することができません。プロトコルのようなセキュリティで保護されたエンコードとデコードをサポートする必要があるので。、私が処理できる例外また、アプリケーションのクラッシュにつながるランタイム例外を投げる前に、代理人に通知しません。
デリゲートメソッドunarchiver(_:cannotDecodeObjectOfClassName:originalClasses:)
は実際にどのシナリオで呼び出されますか?どのように私は聞いて、私のNSSecureCoding
セットアップの下でNSInvalidUnarchiveOperationException
に反応することができますので、デコードが成功しなかったときにランタイムクラッシュを避けることができますか?