😬
[Swift] iOS 12 deprecated NSKeyedArchiverのメソッドを推奨されたものに置き変えた
TL, DR
- コード内の
NSKeyedArchiver
,NSKeyedUnarchiver
のメソッドでiOS 12 deprecatedのものを、推奨されたものに置き換えた。- NSKeyedArchiver
-
archiveData(withRootObject:)
->archiveData(withRootObject:, requireSecureCodign:)
-
- NSKeyedUnarchiver
-
unarchiveObject(with:)
->unarchiveObject(ofClass:, from:)
-
unarchiveTopLevelObjectWithData(_)
->unarchiveObject(ofClass:, from:)
-
- NSKeyedArchiver
- 以下のオブジェクトのarchive/unarchiveの方法を記載(Deprecatedな方法と推奨された方法)
- Bool
- Date
- Strcut
- Class
NSKeyedArchiver, NSKeyedUnarchiverとは
-
NSCoder
のサブクラスで、オブジェクトを、ファイルに保存するのに適した形式で保存できるように、エンコードするメソッドをもつクラス。
-
NSKeyedArchiver
でエンコードしたオブジェクトをデコードするメソッドをもつクラス。
Deprecatedな方法と推奨された方法
Deprecatedな方法
以下のメソッドはiOS 12でdeprecatedした。
NSKeyedArchiver.archiveData(withRootObject: Any)-> Data
NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(_)-> Bool
-
NSKeyedUnarchiver.unarchiveObject(withRootObject: Data)-> Any?
推奨された方法
-
NSKeyedArchiver.archiveData(withRootObject:requiringSecureCoding:)
-
archiveData(withRootObject:)
の置き換え
-
-
NSKeyedUnarchiver.unarchiveObject(ofClass: from:)
-
NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(_)-> Any?
の置き換え -
NSKeyedUnarchiver.unarchiveObject(withRootObject: Data)-> Any?
の置き換え
-
具体的な変更方法
Bool
Deprecatedな方法
func encodeBool_old(bool: Bool) -> Data {
return NSKeyedArchiver.archivedData(withRootObject: bool)
}
func decodeBool_old(data: Data) -> Bool? {
return NSKeyedUnarchiver.unarchiveObject(with: data) as? Bool
}
推奨された方法
func encodeBool_new(bool: Bool) -> Data? {
// 推奨のメソッドに変更
// try? を追加
return try? NSKeyedArchiver.archivedData(withRootObject: bool, requiringSecureCoding: false)
}
func decodeBool_new(data: Data) -> Bool? {
// 推奨のメソッドに変更
return try? NSKeyedUnarchiver.unarchivedObject(ofClasses: [], from: data) as? Bool
}
Date
Deprecatedな方法
func encodeDate_old(date: Date) -> Data {
return NSKeyedArchiver.archivedData(withRootObject: date)
}
func decodeDate_old(data: Data) -> Date? {
return NSKeyedUnarchiver.unarchiveObject(with: data) as? Date
}
推奨された方法
func encodeDate_new(date: Date) -> Data? {
return try? NSKeyedArchiver.archivedData(withRootObject: date, requiringSecureCoding: false)
}
func decodeDate_new(data: Data) -> Date? {
return try? NSKeyedUnarchiver.unarchivedObject(ofClass: NSDate.self ,from: data) as? Date
}
Class
(reference: NSKeyedArchiverとNSKeyedUnarchiverを使ったクラスの保存)
Deprecatedな方法
class MyClass: NSObject, NSCoding {
var num: Int
var bool: Bool
var date: Date
// ~~~ 省略 ~~~
func encode(with coder: NSCoder)
required init?(coder: NSCoder)
}
func encodeClass_old(c: MyClass) -> Data {
return NSKeyedArchiver.archivedData(withRootObject: c)
}
func decodeClass_old(data: Data) -> MyClass? {
return NSKeyedUnarchiver.unarchiveObject(with: data) as? MyClass
}
推奨された方法
class MyClass: NSObject, NSSecureCoding { //<- NSSecureCodingに変更
static var supportsSecureCoding: Bool = true //<- NSSecureCodingの要件
var num: Int
var bool: Bool
var date: Date
// ~~~ 省略 ~~~
func encode(with coder: NSCoder)
required init?(coder: NSCoder)
}
func encodeClass_new(c: MyClass) -> Data? {
// 推奨のメソッドに変更
// try? を追加
return try? NSKeyedArchiver.archivedData(withRootObject: c, requiringSecureCoding: true)
}
func decodeClass_new(data: Data) -> MyClass? {
// 推奨のメソッドに変更
// try? を追加
// `ofClasses`には、`MyClass`と`NSDate`を指定(NSDateの指定は、MyClass内でDate型を使用しているため必要)
return try? NSKeyedUnarchiver.unarchivedObject(ofClasses: [MyClass.self, NSDate.self], from: data) as? MyClass
}
Struct
(reference: UserDefaults で Struct を扱う)
Deprecatedな方法
struct MyStruct: Encodable, Decodable { // <- Json Encode/DecodeしてArchive/Unarchiveするため
var num: Int = 0
var bool: Bool = true
var date: Date = .now
}
func encodeStruct_old(s: MyStruct) -> Data {
guard let encodedData = try? JSONEncoder().encode(s) else {
fatalError()
}
return NSKeyedArchiver.archivedData(withRootObject: encodedData)
}
func decodeStruct_old(data: Data) -> MyStruct? {
guard let data = NSKeyedUnarchiver.unarchiveObject(with: data) as? Data else {
return nil
}
return try? JSONDecoder().decode(MyStruct.self, from: data)
}
推奨された方法
struct MyStruct: Encodable, Decodable {
var num: Int = 0
var bool: Bool = true
var date: Date = .now
}
func encodeStruct_new(s: MyStruct) -> Data? {
guard let encodedData = try? JSONEncoder().encode(s) else {
fatalError()
}
return try? NSKeyedArchiver.archivedData(withRootObject: encodedData, requiringSecureCoding: false)
}
func decodeStruct_new(data: Data) -> MyStruct? {
guard let data = try? NSKeyedUnarchiver.unarchivedObject(ofClass: NSData.self, from: data) as? Data else {
return nil
}
return try? JSONDecoder().decode(MyStruct.self, from: data)
}
Discussion