0

不明なクラスがプロトコルを介して安全にデコードされているNSKeyedUnarchiverアーカイブ解除例外をキャッチしようとしています。NSInvalidUnarchiveOperationExceptionNSSecureCoding

私が使用しているソリューションは、デリゲート プロトコルを実装することにより、関連する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:)

元の投稿とは異なり、decodeTopLevelObjectForKeytry?NSSecureCodingここで説明したように、プロトコルで安全なエンコードとデコードをサポートする必要があるため、 で例外を処理できるクラス関数を使用できません。これは、処理できる例外をスローしない を使用することを強制しますdecodeObject(of:forKey)。また、アプリのクラッシュにつながる実行時例外をスローする前に、デリゲートに通知しません。

デリゲート メソッドunarchiver(_:cannotDecodeObjectOfClassName:originalClasses:)が実際に呼び出されるのはどのようなシナリオですか? デコードが成功しない場合にランタイム クラッシュを回避できるようにNSInvalidUnarchiveOperationException、セットアップでをリッスンして反応するにはどうすればよいですか?NSSecureCoding

4

1 に答える 1