【iOS】extensionを使ってUserDefaultsをちょっといい感じに拡張する


はじめに

仕事で関わっているアプリのコードではUserDefaultsを使用した値の管理方法が整理されていなかったことから、いい感じのUserDefaultsの使い方がないか調べたのでメモしておきます。


拡張しない場合

何も工夫せずUserDefaultsを使うと以下のようになります。
キー名を直接指定する必要があり、キー名のミスや一貫性の欠如といった問題が発生する可能性があります。

// 設定
UserDefaults.standard.set("value1", forKey: "key1")

// 取得
let value1: String = UserDefaults.standard.string(forKey: "key1") ?? ""

// 削除
UserDefaults.standard.removeObject(forKey: "key1")


拡張してみる

調べると、以下の記事のようにextensionを使ってUserDefaultsを拡張する方法が見つかりました。

UserDefaultsの処理をまとめて保守性が高いUserDefaultsの書き方【Swift】 - Reigle 技術ブログ

Benefits of Creating an Extension for User Defaults

ほぼ参考記事のままですが、結論としては以下のようにUserDefaultsを拡張すると良さそうです。

extension UserDefaults {
    private enum Key: String {
        case key1
    }

    var key1: String {
        get {
            string(forKey: Key.key1.rawValue) ?? ""
        }
        set {
            set(newValue, forKey: Key.key1.rawValue)
        }
    }

    func removeKey1() {
        removeObject(forKey: Key.key1.rawValue)
    }
}


拡張することで以下のように書くことができるようになります。プロパティやメソッドを使って値の操作ができるようになったことで、キー名を直接指定する必要がなくなり、型安全性や可読性も向上しました。

// 設定
UserDefaults.standard.key1 = "value1"

// 取得
let value1: String = UserDefaults.standard.key1

// 削除
UserDefaults.standard.removeKey1()


ChatGPTに確認

ChatGPTに「こんな感じでUserDefaults拡張することについてどう思う?」と確認して見ましたが、良いアプローチですとお墨付きをもらいました。

UserDefaultsを拡張することによるメリットをChatGPTに教えてもらったので最後に載せておきます。

  1. 型安全性の強化:特定のキーに対応する値の型が拡張によって明確になります。従って、誤った型のデータを保存または取得するリスクが軽減されます。
  2. 一貫性の維持:UserDefaultsのキーを一元管理することで、誤ったキーでデータを保存または取得するリスクを軽減し、キーの一貫性を保つことができます。
  3. コードの可読性と保守性の向上:UserDefaultsの操作が拡張メソッドおよびプロパティを介して行われるため、コードが整理され、可読性が向上します。また、変更やデバッグが容易になります。
  4. 直感的なAPI:UserDefaultsに保存されている値に対して、プロパティのようなインターフェースでアクセスできるようになるため、コードの理解と使用がより直感的になります。
  5. 明確な削除操作:データの削除は明確なメソッドを通じて行われ、削除操作の意図が明確になります。これにより、間違って値を削除するリスクを軽減できます。