文字っぽいの。

文字を書いています。写真も混ざります。

iOS 12以降のAPIで "NSKeyedArchiver" と "NSKeyedUnarchiver" を使う

環境

  • Swift: version 4.2.1

やりたいこと

NSKeyedArchiverNSKeyedUnarchiver を使って、UserDefaultsやKeyChainに色々入れたり出したりすることがあると思います。iOS 11まではこうやって書いていました。

// ArchiveしてUserDefaultにセット
let rootObject: [Int] = [1, 2, 3, 4, 5]
let archivedData = NSKeyedArchiver.archivedData(withRootObject: rootObject)
UserDefaults.standard.set(archivedData, forKey: "key")

// UserDefaultからゲットしてUnarchiveする
let data = UserDefaults.standard.data(forKey: "key")!
let unarchivedObject = NSKeyedUnarchiver.unarchiveObject(with: data) as? [Int]

print(unarchivedObject) // => Optional([1, 2, 3, 4, 5])

ここで使っている archivedData(withRootObject:)unarchiveObject(with:)iOS 12以降のAPIではDeprecatedになっているので、置き換えます。

// ArchiveしてUserDefaultにセット
let rootObject: [Int] = [1, 2, 3, 4, 5]
let archivedData = try! NSKeyedArchiver.archivedData(withRootObject: rootObject, requiringSecureCoding: false)
UserDefaults.standard.set(archivedData, forKey: "key")

// UserDefaultからゲットしてUnarchiveする
let data = UserDefaults.standard.data(forKey: "key")!
let unarchivedObject = try! NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as? [Int]

print(unarchivedObject) // => Optional([1, 2, 3, 4, 5])

Xcodeからは

'unarchiveObject(with:)' was deprecated in iOS 12.0: Use +unarchivedObjectOfClass:fromData:error: instead

というWarningが出るんですが、素直に unarchivedObjectOfClass(fromData:, error:)を使うと

let unarchivedObject = try! NSKeyedUnarchiver.unarchivedObject(ofClasses: [NSArray.self], from: data) as? [Int]

というコードを書く必要があり(ArrayじゃなくてNSArrayです)難しさが増すので unarchiveTopLevelObjectWithData()を使うのをおすすめします。