概要

テーマ購入・ジャンルアンロックに使用するアプリ内通貨。日次ログイン・動画視聴・プレミアム月次配布で獲得。 AppGroup UserDefaults に残高を保存し、Widget からも参照可能。

関連画面

獲得手段

イベント付与量制約
デイリーログインボーナス+1コイン/日1日1回(lastLoginDateで制限)
プレミアム月次配布+100コイン毎月1日、プレミアムユーザーのみ
動画視聴ボーナス+3コイン1日最大5回

消費手段

項目消費量
有料テーマ購入200コイン
ジャンルアンロック100コイン × 13ジャンル = 1300コイン

収支シミュレーション

1ヶ月(30日)の最大獲得量:
ログイン: 30 × 1 = 30コイン
動画ボーナス: 30 × 5 × 3 = 450コイン
プレミアム: +100コイン(プレミアムのみ)
合計: 480〜580コイン/月

全ジャンル解放(1300)+ テーマ複数(200×N)に必要なため、自然な課金導線。

API

CoinService {
    func getBalance() -> Int
    func recordDailyLogin() -> CoinResult
    func recordMonthlyPremiumBonus() -> CoinResult
    func recordVideoBonus() -> CoinResult
    func spendCoins(_ amount: Int) -> Bool
    func getLoginStreak() -> Int
    func getRemainingVideoBonusCount() -> Int  // 当日の残り回数
}

struct CoinResult {
    let earned: Int
    let streak: Int
    let balance: Int
    let alreadyReceived: Bool
}

ストリーク計算ロジック

// 前日ログイン → 継続 (+1)、そうでなければ 1日目リセット
streak = (lastLogin == yesterday) ? streak + 1 : 1

ビジネスルール

外部連携

連携先用途
AppGroup UserDefaults残高・履歴の保存
RewardedAdManager動画ボーナス時の広告表示
PremiumService月次ボーナス対象判定

エラー処理

発生条件対応
残高不足「コインが足りません」アラート
動画ボーナス上限「本日の上限に達しました」
AppGroup nil標準UserDefaultsへフォールバック

実装メモ

変更履歴

バージョン日付変更内容
1.02026-05-09初版作成