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:
79
Shared/Persisence/SharedModelContainer.swift
Normal file
79
Shared/Persisence/SharedModelContainer.swift
Normal file
@@ -0,0 +1,79 @@
|
||||
//
|
||||
// SharedModelContainer.swift
|
||||
// Feels
|
||||
//
|
||||
// Factory for creating ModelContainer shared between main app and widget extension.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import SwiftData
|
||||
|
||||
enum SharedModelContainer {
|
||||
/// Creates a ModelContainer with the appropriate configuration for app group sharing
|
||||
/// - Parameter useCloudKit: Whether to enable CloudKit sync
|
||||
/// - Returns: Configured ModelContainer
|
||||
static func create(useCloudKit: Bool = false) -> ModelContainer {
|
||||
let schema = Schema([MoodEntryModel.self])
|
||||
let storeURL = Self.storeURL
|
||||
|
||||
let configuration: ModelConfiguration
|
||||
if useCloudKit {
|
||||
// CloudKit-enabled configuration
|
||||
configuration = ModelConfiguration(
|
||||
schema: schema,
|
||||
url: storeURL,
|
||||
cloudKitDatabase: .private(cloudKitContainerID)
|
||||
)
|
||||
} else {
|
||||
// Local-only configuration
|
||||
configuration = ModelConfiguration(
|
||||
schema: schema,
|
||||
url: storeURL,
|
||||
cloudKitDatabase: .none
|
||||
)
|
||||
}
|
||||
|
||||
do {
|
||||
return try ModelContainer(for: schema, configurations: [configuration])
|
||||
} catch {
|
||||
fatalError("Failed to create ModelContainer: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
/// The URL for the SwiftData store in the shared app group container
|
||||
static var storeURL: URL {
|
||||
guard let containerURL = FileManager.default.containerURL(
|
||||
forSecurityApplicationGroupIdentifier: appGroupID
|
||||
) else {
|
||||
fatalError("App Group container not available for: \(appGroupID)")
|
||||
}
|
||||
return containerURL.appendingPathComponent(storeFileName)
|
||||
}
|
||||
|
||||
/// App Group identifier based on build configuration
|
||||
static var appGroupID: String {
|
||||
#if DEBUG
|
||||
return Constants.groupShareIdDebug
|
||||
#else
|
||||
return Constants.groupShareId
|
||||
#endif
|
||||
}
|
||||
|
||||
/// CloudKit container identifier based on build configuration
|
||||
static var cloudKitContainerID: String {
|
||||
#if DEBUG
|
||||
return "iCloud.com.tt.ifeelDebug"
|
||||
#else
|
||||
return "iCloud.com.tt.ifeel"
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Store file name based on build configuration
|
||||
static var storeFileName: String {
|
||||
#if DEBUG
|
||||
return "Feels-Debug.store"
|
||||
#else
|
||||
return "Feels.store"
|
||||
#endif
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user