Migrate from Core Data to SwiftData
- Replace Core Data with SwiftData for iOS 18+ - Create MoodEntryModel as @Model class replacing MoodEntry entity - Create SharedModelContainer for App Group container sharing - Create DataController with CRUD extensions replacing PersistenceController - Update all views and view models to use MoodEntryModel - Update widget extension to use SwiftData - Remove old Core Data files (Persistence*.swift, .xcdatamodeld) - Add EntryType enum with all entry type cases - Fix widget label truncation with proper spacing and text scaling 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
77
Shared/Persisence/DataControllerADD.swift
Normal file
77
Shared/Persisence/DataControllerADD.swift
Normal file
@@ -0,0 +1,77 @@
|
||||
//
|
||||
// DataControllerADD.swift
|
||||
// Feels
|
||||
//
|
||||
// SwiftData CREATE operations.
|
||||
//
|
||||
|
||||
import SwiftData
|
||||
import Foundation
|
||||
|
||||
extension DataController {
|
||||
func add(mood: Mood, forDate date: Date, entryType: EntryType) {
|
||||
// Delete existing entry for this date if present
|
||||
if let existing = getEntry(byDate: date) {
|
||||
modelContext.delete(existing)
|
||||
try? modelContext.save()
|
||||
}
|
||||
|
||||
let entry = MoodEntryModel(
|
||||
forDate: date,
|
||||
mood: mood,
|
||||
entryType: entryType
|
||||
)
|
||||
|
||||
modelContext.insert(entry)
|
||||
EventLogger.log(event: "add_entry", withData: ["entry_type": entryType.rawValue])
|
||||
saveAndRunDataListeners()
|
||||
}
|
||||
|
||||
func fillInMissingDates() {
|
||||
let currentOnboarding = UserDefaultsStore.getOnboarding()
|
||||
var endDate = ShowBasedOnVoteLogics.getCurrentVotingDate(onboardingData: currentOnboarding)
|
||||
// Since it's for views, take away the last date so vote is enabled
|
||||
endDate = Calendar.current.date(byAdding: .day, value: -1, to: endDate)!
|
||||
|
||||
let descriptor = FetchDescriptor<MoodEntryModel>(
|
||||
sortBy: [SortDescriptor(\.forDate, order: .reverse)]
|
||||
)
|
||||
|
||||
guard let entries = try? modelContext.fetch(descriptor),
|
||||
let firstEntry = entries.last else { return }
|
||||
|
||||
let allDates: [Date] = Date.dates(from: firstEntry.forDate, toDate: endDate, includingToDate: true).map {
|
||||
Calendar.current.date(bySettingHour: 0, minute: 0, second: 0, of: $0)!
|
||||
}
|
||||
|
||||
let existingDates: Set<Date> = Set(entries.map {
|
||||
Calendar.current.date(bySettingHour: 0, minute: 0, second: 0, of: $0.forDate)!
|
||||
})
|
||||
|
||||
let missing = Array(Set(allDates).subtracting(existingDates)).sorted(by: >)
|
||||
|
||||
for date in missing {
|
||||
// Add 12 hours to avoid UTC offset issues
|
||||
let adjustedDate = Calendar.current.date(byAdding: .hour, value: 12, to: date)!
|
||||
add(mood: .missing, forDate: adjustedDate, entryType: .filledInMissing)
|
||||
}
|
||||
|
||||
if !missing.isEmpty {
|
||||
EventLogger.log(event: "filled_in_missing_entries", withData: ["count": missing.count])
|
||||
}
|
||||
}
|
||||
|
||||
func fixWrongWeekdays() {
|
||||
let data = getData(startDate: Date(timeIntervalSince1970: 0), endDate: Date(), includedDays: [])
|
||||
for entry in data {
|
||||
entry.weekDay = Calendar.current.component(.weekday, from: entry.forDate)
|
||||
}
|
||||
save()
|
||||
}
|
||||
|
||||
func removeNoForDates() {
|
||||
// Note: With SwiftData's non-optional forDate, this is essentially a no-op
|
||||
// Keeping for API compatibility
|
||||
EventLogger.log(event: "removed_entry_no_for_date", withData: ["count": 0])
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user