LoginSignup
29
20

More than 5 years have passed since last update.

Codableで型を保ったままUserDefaultsに保存する

Last updated at Posted at 2019-01-14

UserDefaultsはちょっとしたデータ保存に便利です。
保存するときStructClassをそのまま保存できれば便利ではないですか?
それができるのです。
UserDefaultsData型を保存可能です。
またStruct、ClassをSwift 4から導入されたCodableプロトコルに準拠すれば、Data型にエンコードできます。
これを組み合わせることで、型をまるごと保存することが可能です。

 開発環境

  • Xcode 10.1
  • Swift 4.2

ソースの全体像

import Foundation

protocol Storable {
    func data(forKey: String) -> Data?
    func set(_ data :Any?, forKey: String)
}

// テスト用スタブのため
extension UserDefaults: Storable{}

// 責務:データの永続化
struct StoreManager {

    let store: Storable

    init(store: Storable = UserDefaults.standard) {
        self.store = store
    }

    func save<T: Codable>(value: T, key: String) throws {
        do {
            let encodedData = try JSONEncoder().encode(value)
            store.set(encodedData, forKey: key)
        } catch let error {
            throw error
        }
    }

    func load<T: Codable>(key: String) -> T? {
        guard let data = store.data(forKey: key) else { return nil }
        do {
            let decode = try JSONDecoder().decode(T.self, from: data)
            return decode
        } catch let error {
            print(error.localizedDescription)
            return nil
        }
    }
}

解説 データの保存

    func save<T: Codable>(value: T, key: String) throws {
        do {
            let encodedData = try JSONEncoder().encode(value)
            store.set(encodedData, forKey: key)
        } catch let error {
            throw error
        }
    }

let encodedData = try JSONEncoder().encode(value)にてCodableに準拠した型をData型に変換しています。

そしてstore.set(encodedData, forKey: key)でUserDefaultsに保存をしています。

解説 データの読み出し

    func load<T: Codable>(key: String) -> T? {
        guard let data = store.data(forKey: key) else { return nil }
        do {
            let decode = try JSONDecoder().decode(T.self, from: data)
            return decode
        } catch let error {
            print(error.localizedDescription)
            return nil
        }
    }

guard let data = store.data(forKey: key) else { return nil }でUserDefaultsからData型を読み出します。
let decode = try JSONDecoder().decode(T.self, from: data)で読み出したData型をデコードします。

まとめ

Codableに準拠したインスタンスをUserDefaultsに保存する方法を解説しました。
型情報があるととても便利です。
ぜひ使ってみてください。

29
20
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
29
20