StoreKitでの課金機能実装が一段落し、次は既存のモデルに新しいプロパティを1つ追加しようとしただけのはずが、アプリを起動した瞬間にクラッシュして、これまで貯めていたデータが全部消えたのかと本気で焦りました。今回はそのときの原因と対処の記録です。
1. プロパティを1つ足しただけでクラッシュした
@Modelで定義していた構造体に、memoという新しいプロパティを1つ追加しただけで、アプリを起動するとクラッシュするようになりました。
@Model
class Task {
var title: String
var isDone: Bool
var memo: String // 追加した1行
}
たったこれだけの変更で動かなくなったことに驚き、コードのどこかにタイプミスがあるはずだと数十分探し回ってしまいました。
2. 原因は「保存済みデータの形」とコードが一致しなくなったこと
原因はコードのミスではなく、端末に既に保存されているデータの構造(スキーマ)と、新しいコードが期待する構造がずれてしまったことでした。
保存済みデータ: { title, isDone }
新しいコード: { title, isDone, memo }
保存済みのデータにはmemoという項目が存在しないため、それを読み込もうとしたSwiftDataが「形が合わない」と判断してエラーになっていたのです。プロパティを増やすというごく普通の変更が、裏では「過去に保存したデータをどう解釈するか」という問題を引き起こしていたと気づきました。
3. デフォルト値を用意していなかった
原因が分かった後、対処法を調べると、新しいプロパティにデフォルト値を用意しておけば、多くの場合は自動的にマイグレーション(データの移行)してくれると分かりました。
@Model
class Task {
var title: String
var isDone: Bool
var memo: String = "" // デフォルト値を追加
}
memo: Stringだけだと「必ず値が必要」という意味になり、過去のデータには値が存在しないため読み込めなくなっていました。= ""のようにデフォルト値を与えることで、「過去のデータにはこの値が入っていたことにする」という補完が効くようになり、クラッシュが解消しました。
4. 開発中は思い切ってアプリを消した方が早いこともあると学んだ
本番のデータ設計ではきちんとマイグレーションを考える必要がありますが、まだ開発中でテストデータしか入っていない段階では、毎回デフォルト値の設計に悩むより、シミュレーターからアプリを一度削除して再インストールした方が早いと気づきました。
シミュレーターでアプリを長押し → 削除 → 再度ビルドして実行
「本番相当の慎重さ」と「開発中の身軽さ」を場面によって使い分けるようになってから、無駄に悩む時間が減りました。テストデータを消しても困らない段階かどうかを、まず自分に確認するようにしています。
まとめ
- モデルにプロパティを追加しただけでも、保存済みデータとの形の不一致でクラッシュすることがある
- 新しいプロパティにはデフォルト値を用意しておくと、多くの場合は自動でマイグレーションされる
- 開発中でテストデータしかない段階では、アプリを削除して作り直す方が早いこともある
- 「本番相当の慎重な設計」と「開発中の身軽な作り直し」を場面で使い分けるとよい
データが消えたと思って焦った経験から、スキーマ変更は「コードを直すだけ」では終わらない作業なのだと実感しました。
次は、プッシュ通知(リモート通知)を実装してつまずいた話をまとめます。
本記事は生成AI(Claude)を活用して執筆・編集しています。内容は実体験に基づき、執筆者本人が確認・監修しています。


コメント