swift4でカスタムオブジェクトをNSUserDefaultsに保存・読込する


環境

Xcode Version 10.0 (10A255)
Apple Swift version 4.2

はじめに

こんなカスタムクラスがあったとして、これをNSUserDefaultsに保存できるようにします。

Task.swift
import Foundation

class Task: NSObject {

    let text: String
    let deadline: Date

    init(text: String, deadline: Date) {
        self.text = text
        self.deadline = deadline
    }

    init(from dictionary: [String: Any]) {
        self.text = dictionary["text"] as! String
        self.deadline = dictionary["deadline"] as! Date
    }
}

実装

カスタムクラスの修正

NSCodingプロトコルに準拠するようにメソッドを追加します。

Task.swift
import Foundation

class Task: NSObject, NSCoding {

    let text: String
    let deadline: Date

    init(text: String, deadline: Date) {
        self.text = text
        self.deadline = deadline
    }

    init(from dictionary: [String: Any]) {
        self.text = dictionary["text"] as! String
        self.deadline = dictionary["deadline"] as! Date
    }

    func encode(with aCoder: NSCoder) {
        aCoder.encode(text, forKey: "text")
        aCoder.encode(deadline, forKey: "deadline")
    }

    required init?(coder aDecoder: NSCoder) {
        text = aDecoder.decodeObject(forKey: "text") as! String
        deadline = aDecoder.decodeObject(forKey: "deadline") as! Date
    }
}

NSUserDefaultsから読み込む

var tasks: [Task]!
let userDefaults = UserDefaults.standard
let taskData = userDefaults.object(forKey: "tasks") as? Data
guard let t = taskData else { return }
let unArchiveData = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(t)
tasks = unArchiveData as? [Task] ?? [Task]()

NSUserDefaultsに保存する

let encodedTask = try? NSKeyedArchiver.archivedData(withRootObject: tasks, requiringSecureCoding: false)
let userDefaults = UserDefaults.standard
userDefaults.set(encodedTask, forKey: "tasks")
userDefaults.synchronize()

以上です

次はNSSecureCodingのパターンを実装して、記事にまとめようと思います