- Add watchOS app target with mood voting UI (5 mood buttons) - Add WidgetKit complications (circular, corner, inline, rectangular) - Add WatchConnectivityManager for bidirectional sync between iOS and watch - iOS app acts as central coordinator - all mood logging flows through MoodLogger - Watch votes send to iPhone via WCSession, iPhone logs and notifies watch back - Widget votes use openAppWhenRun=true to run MoodLogger in main app process - Add #if !os(watchOS) guards to Mood.swift and Random.swift for compatibility - Update SKStoreReviewController to AppStore.requestReview (iOS 18 deprecation fix) - Watch reads user's moodImages preference from GroupUserDefaults for emoji style 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
97 lines
2.2 KiB
Swift
97 lines
2.2 KiB
Swift
//
|
|
// MoodEntryModel.swift
|
|
// Feels
|
|
//
|
|
// SwiftData model replacing Core Data MoodEntry
|
|
//
|
|
|
|
import Foundation
|
|
import SwiftData
|
|
|
|
// MARK: - Entry Type Enum
|
|
|
|
enum EntryType: Int, Codable {
|
|
case listView = 0
|
|
case widget = 1
|
|
case watch = 2
|
|
case shortcut = 3
|
|
case filledInMissing = 4
|
|
case notification = 5
|
|
case header = 6
|
|
case siri = 7
|
|
case controlCenter = 8
|
|
case liveActivity = 9
|
|
}
|
|
|
|
// MARK: - SwiftData Model
|
|
|
|
@Model
|
|
final class MoodEntryModel {
|
|
// Primary attributes - CloudKit requires default values
|
|
var forDate: Date = Date()
|
|
var moodValue: Int = 0
|
|
var timestamp: Date = Date()
|
|
var weekDay: Int = 1
|
|
var entryType: Int = 0
|
|
|
|
// Metadata - CloudKit requires default values
|
|
var canEdit: Bool = true
|
|
var canDelete: Bool = true
|
|
|
|
// Journal & Media (NEW)
|
|
var notes: String?
|
|
var photoID: UUID?
|
|
|
|
// Computed properties
|
|
var mood: Mood {
|
|
Mood(rawValue: moodValue) ?? .missing
|
|
}
|
|
|
|
var moodString: String {
|
|
mood.strValue
|
|
}
|
|
|
|
init(
|
|
forDate: Date,
|
|
mood: Mood,
|
|
entryType: EntryType,
|
|
canEdit: Bool = true,
|
|
canDelete: Bool = true,
|
|
notes: String? = nil,
|
|
photoID: UUID? = nil
|
|
) {
|
|
self.forDate = forDate
|
|
self.moodValue = mood.rawValue
|
|
self.timestamp = Date()
|
|
self.weekDay = Calendar.current.component(.weekday, from: forDate)
|
|
self.entryType = entryType.rawValue
|
|
self.canEdit = canEdit
|
|
self.canDelete = canDelete
|
|
self.notes = notes
|
|
self.photoID = photoID
|
|
}
|
|
|
|
// Convenience initializer for raw values
|
|
init(
|
|
forDate: Date,
|
|
moodValue: Int,
|
|
entryType: Int,
|
|
timestamp: Date = Date(),
|
|
weekDay: Int? = nil,
|
|
canEdit: Bool = true,
|
|
canDelete: Bool = true,
|
|
notes: String? = nil,
|
|
photoID: UUID? = nil
|
|
) {
|
|
self.forDate = forDate
|
|
self.moodValue = moodValue
|
|
self.timestamp = timestamp
|
|
self.weekDay = weekDay ?? Calendar.current.component(.weekday, from: forDate)
|
|
self.entryType = entryType
|
|
self.canEdit = canEdit
|
|
self.canDelete = canDelete
|
|
self.notes = notes
|
|
self.photoID = photoID
|
|
}
|
|
}
|