Codable + UserDefaults で保存する。
正しい保存
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
struct CCC: Codable { var aaa: String var bbb: BBB } struct BBB: Codable { var ccc: String } class TestClass { var c: CCC? func ee() { c = CCC(aaa: "123", bbb: BBB(ccc: "456")) if let data = try? JSONEncoder().encode(c) { UserDefaults.standard.set(data, forKey: "test") print("保存成功") } } func ff() { do { guard let a = UserDefaults.standard.data(forKey: "test") else { throw NSError(domain: "", code: 0, userInfo: nil) } c = try JSONDecoder().decode(CCC.self, from: a) print("読み込み成功") } catch { print("読み込み失敗") } } } |
失敗例(構造体の初期化がNG)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
struct CCC: Codable { var aaa: String var bbb: BBB } struct BBB: Codable { var ccc: String } class TestClass { var c: CCC? func ee() { c?.aaa = "123" c?.bbb.ccc = "456" if let data = try? JSONEncoder().encode(c) { UserDefaults.standard.set(data, forKey: "test") print("保存成功") } } func ff() { do { guard let a = UserDefaults.standard.data(forKey: "test") else { throw NSError(domain: "", code: 0, userInfo: nil) } c = try JSONDecoder().decode(CCC.self, from: a) print("読み込み成功") } catch { print("読み込み失敗") } } } |
その他失敗する原因
- まだ保存(encode+
set)していないdata(forKey: dc_key)がnilになるのは、そもそもそのキーでDataが保存されていない可能性があります。- 保存処理(Codable を
JSONEncoder().encode(...)→UserDefaults.standard.set(encoded, forKey: dc_key))が呼ばれていない、あるいは失敗している。
- 保存時と読み出し時でキーが違う
dc_keyが読み込み時と保存時で差異がある(typo、異なる定義など)- 別の名前空間やプレフィックスを使っていないかを確認。
- 保存に失敗している
JSONEncoder().encode(...)が失敗(例:エンコードできないプロパティがある)try?などでエラーを握りつぶしている → 実際はnilデータが保存されていない
- UserDefaults の同期タイミングの問題
- 非同期に保存 → 読み込み時にはまだデータがセットされていない
UserDefaults.standard.synchronize()は基本不要だが、タイミング依存バグが出ている可能性
- 異なる UserDefaults を参照している
- 例えば App Groups 用の
UserDefaults(suiteName:)を使っているが、読み出し側ではstandardを使っている @EnvironmentObject var SET: SettingManagerで使っているキー/UserDefaults が異なっている
- 例えば App Groups 用の
- 初期起動などで登録されていない
register(defaults:)を使っているが、それだけだとdata(forKey:)は返ってこない(登録ドメインの扱いに注意) Qiita- 初回は必ず
setしてからデコードを試すロジックが必要

コメント