10
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

UserDefaults で Struct を扱う

Last updated at Posted at 2019-04-13

Swift 4 から Codable が使えるようになったので活用しましょう。

UserDefaultsstruct は保存できませんが String は保存できるので、
Codable を適用することで、
struct から JSON(String) に変換(エンコード)して保存
JSON(String) から struct に変換(デコード)して取得
というイメージです。

コード

扱う Struct

Codable を適用します。

struct Person: Codable {
    let name: String
    let age: Int
}

用意した Extension

直で書いてもいいですが、少し便利になるよう用意しました。
try? とかで適当に書いちゃってるのでエラーハンドリングなどどうぞ。

extension Encodable {
    
    var json: Data? {
        let encoder = JSONEncoder()
        return try? encoder.encode(self)
    }
}

extension Decodable {
    
    static func decode(json data: Data?) -> Self? {
        guard let data = data else { return nil }
        let decoder = JSONDecoder()
        return try? decoder.decode(Self.self, from: data)
    }
}

extension UserDefaults {
    
    /// - Warning:
    /// 2020.11.30追記) setCodable ではなく set という関数名にすると、String をセットしたいときに Codable と衝突して Codable 扱いとなってしまうため注意。
    func setCodable(_ value: Codable?, forKey key: String) {
        guard let json: Any = value?.json else { return } // 2020.02.23 追記参照
        self.set(json, forKey: key)
        synchronize()
    }
    
    func codable<T: Codable>(forKey key: String) -> T? {
        let data = self.data(forKey: key)
        let object = T.decode(json: data)
        return object
    }
}

2020.02.23 追記

@nak435 @p_x9 さんのコメントより、ループするとのご指摘をいただき、コードを修正いたしました。
詳しくはコメントをご参照ください。お二方ありがとうございます!

2020.11.30 追記

set(_ value: Codable?, forKey key: String)setCodable(_ value: Codable?, forKey key: String) へと変更しました。
コードコメントをご確認ください。

UserDefaults に保存 / から取得

let persons = [Person(name: "Sato Taro", age: 20), Person(name: "Ito Hanako", age: 10)]

// 保存
UserDefaults.standard.set(persons, forKey: "person")

// 取得
let restoredPersons: [Person]? = UserDefaults.standard.codable(forKey: "person")

// 出力  
print(restoredPersons!)
// [TempProject.Person(name: "Sato Taro", age: 20), TempProject.Person(name: "Ito Hanako", age: 10)]

環境

  • Swift 5
10
11
2

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
10
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?