🐥

UserDefaultsとそのユースケースについてまとめる

2024/09/07に公開

概要

はじめての記事投稿となります。稚拙な部分は多々あると思いますがご容赦ください。visionOS開発をするにあたってUserDefaultsに精通する必要があると思い様々なユースケースについて記載しています。
今後も自分の学びをアウトプットしていきますのでよろしくお願いします!!

UserDefaultsとは

UserDefaultsは、iOSやmacOS, visionOSのアプリでユーザー設定やアプリの状態を簡単に保存・管理するための軽量ストレージ機構です。データベースのようなものと捉えて大丈夫です。キーと値のペアとしてデータを保存し、アプリの再起動後も持続させることができます。サポートされるデータ型は

  • Bool: 真偽値
  • Int: 整数値
  • Float: 浮動小数点値
  • Double: 実数値
  • String: 文字列
  • URL: URL
  • Data: データ型
  • Array: 配列
  • Dictionary: 辞書型

です。
典型的なユースケースとして、ユーザーの選択したテーマやログイン状態、ゲームのハイスコア、フォーム入力の一時保存などがあります。
小さなデータの保存に適しており、使いやすさとパフォーマンスのバランスが取れた保存方法です。ただし、セキュリティが必要なデータや大きなデータの保存には他の手段が推奨されます。

※注意点:アプリ自体を削除するとUserDefaults内のデータも全て消えるので重要なデータをUserDefaultsのみに持たせるべきではありません。

UserDefaultsの代表的なユースケース

  1. アプリの設定(設定値やフラグ)
  • 「ダークモードをONにする」のBool
  • 使用する言語のString
  • テーマカラーのString

などの軽量で、頻繁にアクセスされ、簡単に変更される値。

例)
ダークモード設定のボタンを押したときに以下のコードを実行する。

UserDefaults.standard.set(true, forKey: "isDarkModeEnabled")

また、それをアプリ起動時に呼び出して設定する。

let isDarkModeEnabled = UserDefaults.standard.bool(forKey: "isDarkModeEnabled")
  1. ユーザーの最終アクセス時の状態
  • 最後に開いたタブ

保存処理はタブを選択した際

func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
    // 選択されたタブのインデックスを保存
    let selectedIndex = tabBarController.selectedIndex
    UserDefaults.standard.set(selectedIndex, forKey: "lastSelectedTabIndex")
}

復元処理はアプリ起動時

override func viewDidLoad() {
    super.viewDidLoad()

    // 前回選択されたタブのインデックスを取得
    let savedIndex = UserDefaults.standard.integer(forKey: "lastSelectedTabIndex")
    
    // 有効なインデックスかどうかを確認して設定
    if savedIndex < tabBarController?.viewControllers?.count ?? 0 {
        tabBarController?.selectedIndex = savedIndex
    }
}
  • 最後に開いた画面

保存処置を画面遷移を行った際に実行。

func navigateToViewController(_ identifier: String) {
    // 画面遷移を行う
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let viewController = storyboard.instantiateViewController(withIdentifier: identifier)
    navigationController?.pushViewController(viewController, animated: true)
    
    // 最後に表示された画面のIDを保存
    UserDefaults.standard.set(identifier, forKey: "lastOpenedScreen")
}

復元処理はアプリ起動時。

override func viewDidLoad() {
    super.viewDidLoad()

    // 前回表示されていた画面のIDを取得
    if let lastScreenID = UserDefaults.standard.string(forKey: "lastOpenedScreen") {
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let lastViewController = storyboard.instantiateViewController(withIdentifier: lastScreenID)
        
        // ナビゲーションスタックに画面をセット
        navigationController?.pushViewController(lastViewController, animated: false)
    }
}

このように、アプリが再起動したときにユーザーが前回の状態を再現できるようにするために有効。

  1. アプリの使用回数やその他の簡単な統計データ
  • アプリを開いた回数

使用回数のカウントと保存

func incrementAppLaunchCount() {
    // 現在の使用回数を取得(デフォルトは0)
    let launchCount = UserDefaults.standard.integer(forKey: "appLaunchCount")
    
    // 使用回数を1増加
    UserDefaults.standard.set(launchCount + 1, forKey: "appLaunchCount")
    
    // コンソールに出力(デバッグ用)
    print("アプリの使用回数: \(launchCount + 1)")
}

他にも特定の機能を使った回数などのシンプルな数値データで、頻繁に更新されるが小さなデータ量。

UserDefaultsに適していないデータ例

  1. 大容量データ
  • 画像
  • 動画
  • 大きなJSONデータ

UserDefaultsはメモリに保存されるため、大きなデータを保存するとパフォーマンスが低下し、アプリの消費メモリが増加する。

  1. ユーザーの個人情報
  • パスワード
  • クレジットカード番号
  • ユーザーの位置情報
  • 履歴データ

セキュリティの観点から不適切。こうした情報はKeychainなどの安全なストレージを使うべき。

  1. 頻繁に更新されるリアルタイムデータ
  • ゲームのスコア
  • リアルタイムなチャットメッセージ

UserDefaultsは永続的な保存に向いているが頻繁に変わるデータを保存するには不向き。

  1. アプリケーション全体の状態やモデル
  • アプリ全体の状態
  • 複雑なオブジェクトツリー

データが複雑すぎると適切に処理できないことがあり、データ構造が壊れることがある。

Discussion