今回は、UserDefaultsを用いて端末内に自作したクラスのデータを保存する方法を説明します。
とは言っても、最後まで説明すると長くなるので説明の前に完成したものを載せます。
class Animal: NSObject, NSCoding {
private var id : Int!
private var name : String!
init(id: Int, name: String) {
self.id = id
self.name = name
}
//エンコード関数 forKeyは任意の文字列
func encode(with coder: NSCoder) {
coder.encode(id, forKey: "id")
coder.encode(name, forKey: "name")
}
//デコード関数 forKeyは任意の文字列
required init?(coder aDecoder: NSCoder) {
id = aDecoder.decodeObject(forKey: "id") as? Int
name = aDecoder.decodeObject(forKey: "name") as? String
}
//自作クラス->Data型へ変換
private static func archiveDataArray(indexDataArray: [Animal]) -> Data {
do {
// iOS11以降
if #available(iOS 11.0, *) {
let data = try NSKeyedArchiver.archivedData(withRootObject: indexDataArray, requiringSecureCoding: false)
return data
// iOS11以前
} else {
let data = NSKeyedArchiver.archivedData(withRootObject: indexDataArray)
return data
}
} catch {
fatalError("エンコード失敗")
}
}
//UserDefaultsへデータを保存
public func saveDataArray(indexDataArray: [Animal]) {
UserDefaults.standard.set(Animal.archiveDataArray(indexDataArray: indexDataArray), forKey: "")
}
//UserDefaultsからデータ取得
public func getData() -> [Animal] {
var dataArray = [Animal]()
let storedData = UserDefaults.standard.data(forKey: "")
if storedData != nil {
// iOS11以降
if #available(iOS 11.0, *) {
if let storedData = UserDefaults.standard.object(forKey: "") as? Data {
guard let unarchivedObject = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(storedData) as? [Animal] else {
return [Animal]()
}
dataArray = unarchivedObject!
}
// iOS11以前
} else {
if let storedData = UserDefaults.standard.object(forKey: "") as? Data {
guard let unarchivedObject = NSKeyedUnarchiver.unarchiveObject(with: storedData) as? [Animal] else {
return [Animal]()
}
dataArray = unarchivedObject
}
}
}
return dataArray
}
}
では説明に移ります。
まず始めに。。。
下のような自作クラスを作ったとします。
(クラスに拘りはないので、下記クラスの説明は省きます。。。)
class Animal {
private var id : Int!
private var name : String!
init(id: Int. name: String) {
self.id = id
self.name = name
}
}
このクラスを次にNSObjectとNSCodingのクラスを継承させます。
(*あくまでも、ここでは説明の便宜上、上記クラスを自作クラスに継承させますが、実際に設計の事を考慮するとまた別のクラスを作成するのも手です。)
class Animal: NSObject, NSCoding {
private var id : Int!
private var name : String!
init(id: Int, name: String) {
self.id = id
self.name = name
}
func encode(with coder: NSCoder) {
coder.encode(id, forKey: "id")
coder.encode(name, forKey: "name")
}
required init?(coder aDecoder: NSCoder) {
id = aDecoder.decodeObject(forKey: "id") as? Int
name = aDecoder.decodeObject(forKey: "name") as? String
}
}
次にそれぞれ「自作クラス->Data型変換」のための関数を作成します。
//自作クラス->Data型へ変換
private static func archiveDataArray(indexDataArray: [Animal]) -> Data {
do {
// iOS11以降
if #available(iOS 11.0, *) {
let data = try NSKeyedArchiver.archivedData(withRootObject: indexDataArray, requiringSecureCoding: false)
return data
// iOS11以前
} else {
let data = NSKeyedArchiver.archivedData(withRootObject: indexDataArray)
return data
}
} catch {
fatalError("エンコード失敗")
}
}
最後にUserDefaultsへ保存するための関数、UserDefaultsからデータを取得するための関数を作成して終わりです。
class Animal: NSObject, NSCoding {
:
:
//UserDefaultsへデータを保存
public func saveDataArray(indexDataArray: [Animal]) {
UserDefaults.standard.set(Animal.archiveDataArray(indexDataArray: indexDataArray), forKey: "")
}
//UserDefaultsからデータ取得
public func getData() -> [Animal] {
var dataArray = [Animal]()
let storedData = UserDefaults.standard.data(forKey: "")
if storedData != nil {
// iOS11以降
if #available(iOS 11.0, *) {
if let storedData = UserDefaults.standard.object(forKey: "") as? Data {
guard let unarchivedObject = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(storedData) as? [Animal] else {
return [Animal]()
}
dataArray = unarchivedObject!
}
// iOS11以前
} else {
if let storedData = UserDefaults.standard.object(forKey: "") as? Data {
guard let unarchivedObject = NSKeyedUnarchiver.unarchiveObject(with: storedData) as? [Animal] else {
return [Animal]()
}
dataArray = unarchivedObject
}
}
}
return dataArray
}
:
:
}
サーバーと接続をする必要がないアプリを作成する場合、
UserDefaultsを利用し、ユーザーのデータを端末上に保存しなければならない状況も多いと思います。
結構自分自身も利用する場面が多かったので、
良かったら参考にしてみて下さい。
![【Swift】[24]UIScrollViewをスクロールした際の処理を定義する方法 【Swift】[24]UIScrollViewをスクロールした際の処理を定義する方法](https://ediienote.com/Wp_ediieNote/wp-content/uploads/2019/06/swift23-480x320.png)