UserDefaultsは少量のデータを永続的にアプリ内部で保存できます。
暗号化はされていないためユーザー情報等の保存には向きません。
容量は4194304bytes。アプリ削除で共に消えます。
アプリの設定等の簡単なデータ管理に使うのが良いかもしれません。
AppStorage
UserDefaultsの扱いを簡単にしたもの、そのままViewを跨いで自動保存される変数として使える
※扱いが簡単なだけに微妙な動きもするみたいです。自分はまだその状態に陥っていないのでよくわかっていません。
|
1 |
@AppStorage("キー") var a: Bool = false |
@AppStorageはどこでも呼び出せる&保存している状態でコードから消しても問題ない
**AppStorage は “View のプロパティラッパー” なので、
クラスをインスタンス化しても値は共有されます。**
@AppStorage は View(構造体)のプロパティに付けるためのラッパー です。
|
1 |
@AppStorage("username") var username: String = "" |
|
1 2 3 4 5 |
これは内部的には: UserDefaults.standard key = "username" に紐づいています。 そして、同じ key を使えばどの View からでも共有できます。 |
❗ しかし重要な注意点
@AppStorage は ObservableObject の class に付けるべきではない!
理由:
@AppStorageは View のライフサイクルと SwiftUI の更新サイクルに統合されるための仕組み- クラスに付けると 更新通知の挙動が不安定になり、再描画されない / 予期せず更新される などの問題が発生しやすい
Apple 公式も「View に付けること」を前提としています。
key さえ同じなら どの View からでも同じ値にアクセスできます。
例:
|
1 2 3 4 5 6 7 |
struct AView: View { @AppStorage("color") var color: String = "red" } struct BView: View { @AppStorage("color") var color: String = "red" } |
✔️ どう書くのがベスト?
ベスト構成はこれ:
- UserDefaults に保存される永続データ
→ AppDataStore(ObservableObject の保存用クラス)がUserDefaults.standardと直接やりとりする
→@AppStorageは使わない(View にも使わない) - View の簡易設定(テーマ、トグル、フラグなど)
→ View に @AppStorage を使う(軽い設定のみ)
1️⃣ データ管理クラスに UserDefaults の get/set を実装する
|
1 2 3 4 5 6 7 8 9 10 |
class AppDataStore: ObservableObject { @Published var selectedColor: String = "" { didSet { UserDefaults.standard.set(selectedColor, forKey: "color") } } init() { selectedColor = UserDefaults.standard.string(forKey: "color") ?? "red" } } |
2️⃣ View は @EnvironmentObject で参照
|
1 2 3 4 5 6 7 |
struct ContentView: View { @EnvironmentObject var data: AppDataStore var body: some View { Text(data.selectedColor) } } |
✔️ 最後にもう一度まとめ
◉ 同じ key の AppStorage はどこからでも共有される
→ これは OK
◉ しかし class(ObservableObject)に @AppStorage を付けるのは NG
→ SwiftUI の想定外の挙動になる
✔️ AppStorage はただの「UserDefaults への窓口」
@AppStorage("key") は
ただ単に:
|
1 |
UserDefaults.standard["key"] |
を読み書きする“便利ラッパー”です。
AppStorage のプロパティを削除しても
UserDefaults のデータには 一切影響しません。
keyの誤字
keyの誤字は検知されない、通常の変数は宣言されていないものを使おうとするとIDEに怒られるがUserDefaultsはスルーされる
変数に入れて使うと良い
|
1 2 3 4 5 6 7 |
var i: Int = 111 UserDefaults.standard.set(i, forKey: "aaa") let j: Int = UserDefaults.standard.integer(forKey: "aa") //NG、keyのタイプミスが指摘されず0が入る、数値型以外はオプショナル型のnil設定次第 let key: String = "kagi" UserDefaults.standard.set(i, forKey: key) |
メソッド
|
1 2 3 4 5 6 |
UserDefaults.standard.set(保存する値, forKey: "キー") //データ保存 UserDefaults.standard.integer(forKey: "キー") //読み込み UserDeafaults.standard.removeObject(forKey: "キー") //削除 let appDomain = Bundle.main.bundleIdentifier UserDefaults.standard.removePersistentDomain(forName: appDomain!) //データの一括削除 |
扱える型一覧
|
1 2 3 4 5 6 7 8 9 10 11 |
UserDefaults.standard.object(forKey: "キー") UserDefaults.standard.string(forKey: "キー") UserDefaults.standard.array(forKey: "キー") UserDefaults.standard.dictionary(forKey: "キー") UserDefaults.standard.data(forKey: "キー") UserDefaults.standard.stringArray(forKey: "キー") UserDefaults.standard.integer(forKey: "キー") UserDefaults.standard.float(forKey: "キー") UserDefaults.standard.double(forKey: "キー") UserDefaults.standard.bool(forKey: "キー") UserDefaults.standard.url(forKey: "キー") |
保存場所
/AppData/Library/Preferences/ 内の [bundle-identifier].plist

コメント