【Swift5】カスタムクラスをUserDefaultsへ保存する


カスタムクラスでスマートにコーディングするぜ!

みなさんご存知の通り、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
    }
}

やり方は、いつものカスタムクラスにencodedecodeに関する処理を書いておくだけです。

保存

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で失敗した時のエラーハンドリングもした方が丁寧です。