エラー分類の方針
- ビジネスエラー: コイン残高不足等、UIでアラート表示
- リソースエラー: Bundle JSON読込失敗。空リスト返却 + Logger.error()
- 広告エラー: ロード失敗時はサイレント、表示失敗時のみコールバックで通知
- StoreKitエラー: 購入失敗・検証失敗を
PurchaseError でラップ
- 権限エラー: 通知許可拒否・ATT拒否は設定アプリ誘導
定義済み Error 型
PurchaseError(StoreKit)
enum PurchaseError: LocalizedError {
case productNotFound
case verificationFailed
case pending
var errorDescription: String? {
switch self {
case .productNotFound: return "商品が見つかりません"
case .verificationFailed: return "購入の検証に失敗しました"
case .pending: return "購入処理中です"
}
}
}
エラー一覧
| エラーID |
分類 |
発生条件 |
ユーザー表示 |
復旧方法 |
ロギング |
| DT-COIN-01 |
ビジネス |
テーマ購入時の残高不足 |
「コインが足りません」 |
動画視聴で補充 |
info |
| DT-COIN-02 |
ビジネス |
ジャンル購入時の残高不足 |
「コインが足りません」 |
動画視聴で補充 |
info |
| DT-COIN-03 |
ビジネス |
動画ボーナス上限到達(5回/日) |
「本日の上限に達しました」 |
翌日まで待機 |
info |
| DT-RES-01 |
リソース |
daily_tips.json 読込失敗 |
「豆知識を取得できませんでした」(空表示) |
アプリ再起動 / 再インストール |
error |
| DT-RES-02 |
リソース |
ジャンルクイズJSON読込失敗 |
「問題を取得できませんでした」 |
アプリ再起動 |
error |
| DT-AD-01 |
広告 |
Rewarded広告ロード失敗 |
「広告を取得できませんでした」 |
onFailedコールバック → 再試行 |
warning |
| DT-AD-02 |
広告 |
Interstitial広告未ロード |
サイレント(次に進む) |
— |
info |
| DT-AD-03 |
広告 |
AppOpen広告ロード失敗 |
サイレント |
— |
info |
| DT-SK-01 |
StoreKit |
productNotFound |
「商品が見つかりません」 |
復元ボタン誘導 |
error |
| DT-SK-02 |
StoreKit |
verificationFailed |
「購入の検証に失敗しました」 |
サポート問い合わせ |
error |
| DT-SK-03 |
StoreKit |
pending(保護者承認待ち等) |
「購入処理中です」 |
承認後に自動更新 |
info |
| DT-PERM-01 |
権限 |
通知許可拒否 |
「通知設定を有効にしてください」 |
設定アプリ起動 |
info |
| DT-PERM-02 |
権限 |
ATT拒否 |
サイレント(パーソナライズ広告のみ無効化) |
— |
info |
| DT-WID-01 |
整合性 |
AppGroup UserDefaultsが nil |
Widget空表示 |
本体起動で同期 |
warning |
UI 表示パターン
| 重要度 | 表示形式 | 例 |
| 低 | サイレント / Logger のみ | 広告ロード失敗、ATT拒否 |
| 中 | Alert ダイアログ | 残高不足、StoreKit失敗 |
| 高 | フルスクリーン誘導 | 該当なし(ローカル完結アプリ) |
広告エラーのハンドリング戦略
本アプリは広告に強く依存しているため、広告ロード失敗時は
UXを止めない方針:
- Banner: ロード失敗→ View 非表示(高さ0)
- Interstitial: 未ロード→ そのまま次画面へ
- Rewarded: 必須なので onFailed で「もう一度お試しください」
- AppOpen: 起動UXを阻害しないようロード失敗はサイレント
変更履歴
| バージョン | 日付 | 変更内容 |
| 1.0 | 2026-05-09 | 初版作成(ソースコードからリバース) |