SwiftData @Model + AppGroup UserDefaults(Widget/LiveActivity共有)
@Model final class StudySession {
var id: UUID = UUID()
var startTime: Date = Date()
var endTime: Date?
var duration: TimeInterval = 0
var subject: Subject?
var date: Date { Calendar.current.startOfDay(for: startTime) }
}
@Model final class Subject {
var id: UUID = UUID()
var name: String = ""
var colorHex: String = "#007AFF"
var iconName: String = "book"
var sortOrder: Int = 0
var createdAt: Date = Date()
var currentScore: Int?
var targetScore: Int?
@Relationship(deleteRule: .cascade, inverse: \StudySession.subject)
var sessions: [StudySession] = []
}
@Model final class UserSettings {
var dailyGoalMinutes: Int? = nil
var reminderEnabled: Bool = false
var reminderHour: Int = 19
var reminderMinute: Int = 0
var goalType: String? // "定期テスト" / "高校受験" / "大学受験"
var schoolName: String?
var motivation: String?
var examDate: Date?
}
struct StudyActivityAttributes: ActivityAttributes {
var subjectName: String
var subjectColorHex: String
var subjectIconName: String
var startTime: Date
struct ContentState: Codable {
var elapsedSeconds: Int
var subjectName: String
}
}
AppGroup: group.com.happyboy1002.StudyStopwatch
| キー | 型 | 用途 |
|---|---|---|
activeTimer_startTime | Date | タイマー開始日時(永続化) |
activeTimer_subjectID | String (UUID) | タイマー科目ID |
todayStudySeconds | Int | 本日の学習時間(Widget用) |
dailyGoalMinutes | Int | 日次目標(Widget用) |
schoolName | String | 志望校名 |
examDate | Date | 試験日 |
streakDays | Int | 連続学習日数 |
themeAccentHex | String | テーマカラー |
onboardingCompleted | Bool | オンボーディング完了 |
appearanceMode | String | 外観モード(system/light/dark) |
GoalType: regularExam / highSchoolEntrance / universityEntranceShareCardType: daily / summary / heatmap / graphShareCardTheme: 複数テーマ(無料/プレミアム)ShareSummaryPeriod: week / monthShareGraphType: line / barOnboardingPage: welcome / goalType / subject / score / motivation / exam / target / commit / paywallPomodoroPhase: focus(25分) / shortBreak(5分)| バージョン | 日付 | 変更内容 |
|---|---|---|
| 1.0 | 2026-05-09 | 初版作成 |