カスタムクラスでスマートにコーディングするぜ!
みなさんご存知の通り、Swiftにももちろんカスタムクラスを作る機能があります。
しかし!カスタムクラスはUserDefaultsに直接保存できない!(Realm使えよ)
そこでSwift5でのUserDefalutsへのカスタムクラス保存をまとめておきます。
カスタムクラスをバイナリ形式に変換する
Task.swift
import UIKit
class Task: NSObject, NSCoding {
var name: String!
var date: Date!
// 初期化
init(id: Int, name: String, date: Date) {
self.name = name
self.date = date
}
// ここから変換用コード
// NSKeyedArchiverで呼び出されるエンコード処理
func encode(with coder: NSCoder) {
coder.encode(self.name, forKey: "name")
coder.encode(self.date, forKey: "date")
}
// NSKeyedUnarchiverで呼び出されるデコード処理
required init?(coder: NSCoder) {
name = coder.decodeObject(forKey: "name") as? String
date = coder.decodeObject(forKey: "date") as? Date
}
}
やり方は、いつものカスタムクラスにencode
とdecode
に関する処理を書いておくだけです。
保存
ViewController.swift
// 保存するカスタムクラスを含む配列
var tasksArray: [Task] = []
let task = Task.init(name: "タスク名", date: Date())
tasksArray.append(task)
// バイナリ形式にエンコード
let data = try! NSKeyedArchiver.archivedData(withRootObject: tasksArray, requiringSecureCoding: false)
// 変換したものをUserDefaultsへ保存
UserDefaults.standard.set(tasksArrayData, forKey: "tasksArray")
取得
ViewController.swift
// バイナリ形式のものをUserDefaultsから取得
let data = UserDefaults.standard.object(forKey: "tasksArray") as! Data
// 取得したものをデコード
tasksArray = try! NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as! [Task]
こんな感じ。
おしまい
ほんとはtryで失敗した時のエラーハンドリングもした方が丁寧です。