継続トレーニング日数とバッジシステム
連続トレーニング日数(ストリーク)の計算と、各種実績バッジの判定機能。 継続のモチベーション維持を狙う。
@MainActor
final class AchievementService {
func calculateStreak(sessions: [WorkoutSession]) -> Int
func checkAchievements(sessions: [WorkoutSession]) -> [Achievement]
}
| バッジ名 | 条件 |
|---|---|
| First Step | 初回セッション完了 |
| Consistency | 10セッション完了 |
| Half Century | 50セッション完了 |
| Centurion | 100セッション完了 |
| Streak 3 | 3日連続 |
| Streak 7 | 7日連続 |
| Streak 14 | 14日連続 |
| Streak 30 | 30日連続 |
| First PR | 初回PR達成 |
| PR Machine | 10PR達成 |
| Goal Achieved | 目標達成 |
| Monthly Perfect | 月間目標 4週連続達成 |
// 昨日トレーニングしていれば streak +1
// 当日のみなら 1 開始
// 2日以上空いていれば 0 リセット
func calculateStreak(sessions: [WorkoutSession]) -> Int {
let sortedDates = sessions.map { $0.date }.sorted()
var streak = 0
var prev = Date.distantPast
for date in sortedDates {
if Calendar.current.isDate(date, inSameDayAs: prev) { continue }
if Calendar.current.isDate(date, inSameDayAs: prev.advanced(by: 86400)) {
streak += 1
} else {
streak = 1
}
prev = date
}
return streak
}
| バージョン | 日付 | 変更内容 |
|---|---|---|
| 1.0 | 2026-05-09 | 初版作成 |