web-dev-qa-db-ja.com

iOS 12でNSKeyedArchiverの初期化子init(forWritingWith :)を置き換えて、CKRecordのメタデータをエンコードする方法

IOS 12では、NSKeyedArchiverの初期化子init(forWritingWith :)は非推奨になりました。 Xcode 10では、新しい初期化子init(requiringSecureCoding :)に置き換えることをお勧めします。問題は、この初期化子がNSCoderオブジェクトのrequiresSecureCodingプロパティの値のみを設定し、エンコードされたデータを含むNSMutableDataオブジェクトを設定しないことです。以下は、CKRecord(CloudKitレコード)のメタデータをエンコードするためにAppleによって提案された元のコードです。

let data = NSMutableData()
let coder = NSKeyedArchiver.init(forWritingWith: data)
coder.requiresSecureCoding = true
record.encodeSystemFields(with: coder)
coder.finishEncoding()

CKRecordクラスのencodeSystemFieldsメソッドにはNSKeyedArchiverオブジェクト(NSCoderサブクラス)が必要であり、エンコードされたデータはこのオブジェクトに関連付けられたNSMutableDataオブジェクトに格納されます。 init(forWritingWith :)イニシャライザーをinit(requiringSecureCoding :)イニシャライザーに置き換えると、NSKeyedArchiverオブジェクトが取得されますが、このオブジェクトはNSMutableDataオブジェクトに関連付けられていないため、レコードのメタデータを取得できません。 NSKeyedArchiverオブジェクトによって生成されたデータをNSMutableDataオブジェクトに取得するためのコードを完成させる方法がわかりません。

7
Mikiko Jane

いくつかのリリースでは、NSKeyedArchiverencodedDataメソッド があります。これはアーカイバで_-finishEncoding_を呼び出し、アーカイバが持っている最終的なエンコードされたデータを返します。作成した。これは、_-[NSKeyedArchiver init]_を介して初期化するときに完成したデータを取得する方法です。

_let coder = NSKeyedArchiver()
/* encode stuff */
let data = coder.encodedData
_

これにより、NSMutableDataバリアントが不要になり、この更新により、可変データバリアントは非推奨になり、新しいパラダイムが採用されました。だから書くのではなく

_let data = NSMutableData()
let coder = NSKeyedArchiver.init(forWritingWith: data)
coder.requiresSecureCoding = true
record.encodeSystemFields(with: coder)
coder.finishEncoding()
_

あなたが書くだろう

_let coder = NSKeyedArchiver(requiringSecureCoding: true)
record.encodeSystemFields(with: coder)
let data = coder.encodedData
_

_.requiresSecureCoding_への手動割り当てと手動finishEncoding()呼び出しの両方が不要になりました。


このダンスは、CKRecord.encodeSystemFields(with:)を呼び出す場合にのみ必要であることに注意してください。これは、それ自体のサブセットのみをエンコードするために明示的にNSCoderを取ります。オブジェクトをエンコードする一般的なケースでは、 新しいNSKeyedArchiver.archivedData(withRootObject:requiringSecureCoding:)メソッド :を使用します。

_let data = try NSKeyedArchiver.archivedData(withRootObject: /* object */, requiringSecureCoding: true)
_

これは

_let coder = NSKeyedArchiver(requiringSecureCoding: true)
coder.encodeObject(/* object */, forKey: NSKeyedArchiveRootObjectKey)
let data = coder.encodedData
_
12
Itai Ferber