Search code examples
swiftswiftuiswiftdata

SwiftData: Thread 1: "NSFetchRequest could not locate an NSEntityDescription for entity name 'Reminder'"


How do I fix:

Thread 1: "NSFetchRequest could not locate an NSEntityDescription for entity name 'Reminder'

I have read in another post that if I change order of configurations, then it would work. But by doing so, I just change the model which makes the app crash.

import SwiftUI
import SwiftData
import CoreData
#if os(iOS) || os(macOS) || os(watchOS)
import WidgetKit
#endif

@main
struct Main: App {
    @Environment(\.scenePhase) private var scenePhase
    
    @StateObject var statsViewModel = StatsViewModel()
    @StateObject var badgeViewModel = BadgeViewModel()
    @StateObject var localNotificationManager = LocalNotificationManager()
    
    @AppStorage("notifications") var notificationsSet: Bool = false
    
    @Environment(\.modelContext) private var modelContext
        
    let container: ModelContainer
    
    init(){
        let fileContainer = URL.storeURL(for: "group.Water-Alert-App", databaseName: "CoreData")
        
        let defaultDirectoryURL = NSPersistentContainer.defaultDirectoryURL()
        
        let localSchema = Schema([Reminder.self])
        let cloudSchema = Schema([Goal.self, WaterData.self, Container.self])
        
        let localConfiguration = ModelConfiguration("Local", schema: localSchema, url: defaultDirectoryURL.appendingPathComponent("Local.sqlite"))
        
        let cloudConfiguration = ModelConfiguration("Cloud", schema: cloudSchema, url: fileContainer, cloudKitDatabase: .private("iCloud.Water-Alert-App-Offical"))
        
        container = try! ModelContainer(for:  Reminder.self, Goal.self, WaterData.self, Container.self, configurations: cloudConfiguration, localConfiguration)
    }
    
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(statsViewModel)
                .environmentObject(badgeViewModel)
                .environmentObject(localNotificationManager)
                .task {
                    if !notificationsSet {
                        do{
                            try await localNotificationManager.reqeustAuthorization()
                            await localNotificationManager.setUpNotificationsAtStart()
                        } catch{
                            
                        }
                    }
                    notificationsSet = true
                }
            
        }
        .modelContainer(container)
        .onChange(of: scenePhase) { _, phase in
            if phase == .active{
                Task{
#if os(iOS) || os(macOS) || os(watchOS)
                    WidgetCenter.shared.reloadAllTimelines()
#endif
                    
                    await localNotificationManager.getCurrentSettings()
                    await localNotificationManager.getPendingRequest()
                }
            } else if phase == .background{
                do {
#if os(iOS) || os(macOS) || os(watchOS)
                    WidgetCenter.shared.reloadAllTimelines()
#endif
                    
                    try modelContext.save()
                } catch  {
                    print(error)
                }
            }
        }

This is the code that makes the app crash and the app crashes only when I access Reminder model through a Query in a view.


Solution

  • From Apple DTS:

    This is an issue on the framework side – when an app uses a ModelContainer with multiple ModelConfiguration to manage multiple stores, only the model types specified in the first configuration are loaded, and that triggers the error.

    This issue should have been fixed in iOS 17.4, which is now beta 2. You can download the beta and give it a try. Feel free to follow up if the issue is still there.

    If you would like to support versions before 17.4, consider creating one container per configuration.