Fix build errors, resolve all warnings, and improve code quality
Widget Extension Fixes: - Create standalone WidgetDataProvider for widget data isolation - Add WIDGET_EXTENSION compiler flag for conditional compilation - Fix DataController references in widget-shared files - Sync widget version numbers with main app (23, 1.0.2) - Add WidgetBackground color to asset catalog Warning Resolutions: - Fix UIScreen.main deprecation in BGView and SharingListView - Fix Text '+' concatenation deprecation in PurchaseButtonView and SettingsTabView - Fix exhaustive switch in BiometricAuthManager (add .none case) - Fix var to let in ExportService (3 instances) - Fix unused result warning in NoteEditorView - Fix ForEach duplicate ID warnings in MonthView and YearView Code Quality Improvements: - Wrap bypassSubscription in #if DEBUG for security - Rename StupidAssCustomWidgetObservableObject to CustomWidgetStateViewModel - Add @MainActor to IconViewModel - Replace fatalError with graceful fallback in SharedModelContainer - Add [weak self] to closures in DayViewViewModel - Add OSLog-based AppLogger for production logging - Add ImageCache with NSCache for memory efficiency - Add AccessibilityHelpers with Reduce Motion support - Create DataControllerProtocol for dependency injection - Update .gitignore with secrets exclusions 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -7,14 +7,33 @@
|
||||
|
||||
import Foundation
|
||||
import SwiftData
|
||||
import os.log
|
||||
|
||||
/// Errors that can occur when creating the shared model container
|
||||
enum SharedModelContainerError: LocalizedError {
|
||||
case appGroupNotAvailable(String)
|
||||
case modelContainerCreationFailed(Error)
|
||||
|
||||
var errorDescription: String? {
|
||||
switch self {
|
||||
case .appGroupNotAvailable(let groupID):
|
||||
return "App Group container not available for: \(groupID)"
|
||||
case .modelContainerCreationFailed(let error):
|
||||
return "Failed to create ModelContainer: \(error.localizedDescription)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum SharedModelContainer {
|
||||
private static let logger = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.tt.ifeel", category: "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 {
|
||||
/// - Throws: SharedModelContainerError if creation fails
|
||||
static func create(useCloudKit: Bool = false) throws -> ModelContainer {
|
||||
let schema = Schema([MoodEntryModel.self])
|
||||
let storeURL = Self.storeURL
|
||||
let storeURL = try Self.storeURL
|
||||
|
||||
let configuration: ModelConfiguration
|
||||
if useCloudKit {
|
||||
@@ -36,18 +55,44 @@ enum SharedModelContainer {
|
||||
do {
|
||||
return try ModelContainer(for: schema, configurations: [configuration])
|
||||
} catch {
|
||||
fatalError("Failed to create ModelContainer: \(error)")
|
||||
logger.error("Failed to create ModelContainer: \(error.localizedDescription)")
|
||||
throw SharedModelContainerError.modelContainerCreationFailed(error)
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a ModelContainer, falling back to in-memory storage if shared container fails
|
||||
/// - Parameter useCloudKit: Whether to enable CloudKit sync
|
||||
/// - Returns: Configured ModelContainer (shared or in-memory fallback)
|
||||
static func createWithFallback(useCloudKit: Bool = false) -> ModelContainer {
|
||||
do {
|
||||
return try create(useCloudKit: useCloudKit)
|
||||
} catch {
|
||||
logger.warning("Falling back to in-memory storage due to: \(error.localizedDescription)")
|
||||
// Fall back to in-memory storage
|
||||
let schema = Schema([MoodEntryModel.self])
|
||||
let config = ModelConfiguration(schema: schema, isStoredInMemoryOnly: true)
|
||||
do {
|
||||
return try ModelContainer(for: schema, configurations: [config])
|
||||
} catch {
|
||||
// This should never happen with in-memory storage, but handle it gracefully
|
||||
logger.critical("Failed to create even in-memory ModelContainer: \(error.localizedDescription)")
|
||||
preconditionFailure("Unable to create ModelContainer: \(error)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The URL for the SwiftData store in the shared app group container
|
||||
/// - Throws: SharedModelContainerError if app group is not available
|
||||
static var storeURL: URL {
|
||||
guard let containerURL = FileManager.default.containerURL(
|
||||
forSecurityApplicationGroupIdentifier: appGroupID
|
||||
) else {
|
||||
fatalError("App Group container not available for: \(appGroupID)")
|
||||
get throws {
|
||||
guard let containerURL = FileManager.default.containerURL(
|
||||
forSecurityApplicationGroupIdentifier: appGroupID
|
||||
) else {
|
||||
logger.error("App Group container not available for: \(appGroupID)")
|
||||
throw SharedModelContainerError.appGroupNotAvailable(appGroupID)
|
||||
}
|
||||
return containerURL.appendingPathComponent(storeFileName)
|
||||
}
|
||||
return containerURL.appendingPathComponent(storeFileName)
|
||||
}
|
||||
|
||||
/// App Group identifier based on build configuration
|
||||
|
||||
Reference in New Issue
Block a user