不明なクラスがプロトコルを介して安全にデコードされているNSKeyedUnarchiver
アーカイブ解除例外をキャッチしようとしています。NSInvalidUnarchiveOperationException
NSSecureCoding
私が使用しているソリューションは、デリゲート プロトコルを実装することにより、関連するNSKeyedUnarchiverDelegate SO 投稿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
}
myは、私が指摘した元のNSKeyedUnarchiverDelegate SO 投稿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:)
指定された名前のクラスがデコード中に使用できないことをデリゲートに通知します。
しかし、私の場合、このメソッドは上記のスニペットでは呼び出されません (ただし、デコードで問題が発生しない場合は、unarchiverWillFinish(_:)
またはのような他のデリゲート メソッドが通常どおり呼び出されます。unarchiver(_:didDecode:)
元の投稿とは異なり、decodeTopLevelObjectForKey
try?
NSSecureCoding
ここで説明したように、プロトコルで安全なエンコードとデコードをサポートする必要があるため、 で例外を処理できるクラス関数を使用できません。これは、処理できる例外をスローしない を使用することを強制しますdecodeObject(of:forKey)
。また、アプリのクラッシュにつながる実行時例外をスローする前に、デリゲートに通知しません。
デリゲート メソッドunarchiver(_:cannotDecodeObjectOfClassName:originalClasses:)
が実際に呼び出されるのはどのようなシナリオですか? デコードが成功しない場合にランタイム クラッシュを回避できるようにNSInvalidUnarchiveOperationException
、セットアップでをリッスンして反応するにはどうすればよいですか?NSSecureCoding