7 Replies
      Latest reply on Oct 24, 2019 7:06 PM by yvsong
      bryonCat Level 1 Level 1 (0 points)

        I am getting an error when trying to fetch objects in SwiftUi in a form sheet modal in iOS 13.

         

        Here's the error:

        [SwiftUI] Context in environment is not connected to a persistent store coordinator: <NSManagedObjectContext: 0x600003218620>

         

        I am able to run a fetchRequest from a list view, but not in the modal.

        Has anyone else seen this issue?

         

        I set the Environment context in the SceneDelegate:

         

        if let windowScene = scene as? UIWindowScene {
              let window = UIWindow(windowScene: windowScene)
              let managedObjectContext = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
              //managedObjectContext.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy
              window.rootViewController = UIHostingController(rootView: ContentView().environmentObject(sampleViewModel).environmenbject(customerViewModel).environment(\.managedObjectContext, managedObjectContext))
              self.window = window
              window.makeKeyAndVisible()

         

        In the ContentView:

        import SwiftUI
        
        struct ContentView: View {
            @State var isPresented = false
            
            var body: some View {
                NavigationView {
                    VStack {
                        // Search bar, filter, and divider
                        SampleListView()
                    }
                    .sheet(isPresented: $isPresented) {
                        NewSampleView()
                    }
                    .navigationBarTitle("Samples")
                    AddSampleButton(isNewSamplePresented: $isPresented)
                }
            }
        }

         

        Able to see items in the SampleListView:

        struct SampleListView: View {
            @EnvironmentObject var viewModel: SampleListViewModel
            @FetchRequest(fetchRequest: Sample.allSamplesFetchRequest()) var samples: FetchedResults
            var body: some View {
        
                List(self.samples) { sample in
                    VStack(alignment: HorizontalAlignment.leading) {
                        NavigationLink(destination: SampleView(activeSampleModel: ActiveSampleViewModel(sample: sample))) {
                            Spacer()
                            Text(sample.trackingNumber ?? "")
                            Spacer()
                            Text(sample.sampleId ?? "")
                            Spacer()
                        }
                    }
        
                }
            }
        }

         

        But I get the error when presenting the NewSampleView (I've tried using a fetchRequest defined in the view as well as one defined in the NSManagedObject subclass but the fetch is always failing with the above error) :

        import SwiftUI
        import CoreData
        
        struct NewSampleView : View {
            @State var customerId = ""
            @State var sampleDate = Date(timeIntervalSinceNow: 0)
            @State var receiptDate = Date(timeIntervalSinceNow: 0)
            @State var customerServiceSampleNumber = ""
            @State var notes = ""
        
            @Environment(\.managedObjectContext) var managedObjectContext
            @FetchRequest(fetchRequest: fetchRequest(), animation: nil) var customers: FetchedResults
            
            var body: some View {
                
                List(self.customers) { customer in
                    VStack(alignment: HorizontalAlignment.leading) {
                            Spacer()
                            Text(customer.customerId ?? "")
                            Spacer()
                        }
                    }
            }
            
            
            static func fetchRequest() -> NSFetchRequest {
                let request: NSFetchRequest = Customer.fetchRequest() as! NSFetchRequest
                request.sortDescriptors = [NSSortDescriptor(key: "name", ascending: true)]
                  
                return request
            }
        • Re: SwiftUI and CoreData
          KKLB Level 1 Level 1 (10 points)

          Hi bryonCat

          I found similiar issue. It seems to be general problem of beta 5. Just create Hello World project and pass any EnviromentalObject to modal view. You should get the same error message.

          • Re: SwiftUI and CoreData
            bryonCat Level 1 Level 1 (0 points)

            Thanks, that's what I was thinking - everything works if I don't use a modal - hope it's all fixed up in beta 6.

            • Re: SwiftUI and CoreData
              RΔSΞC Level 1 Level 1 (0 points)

              Xcode 11 GM seed 1 and it seems this is still an issue unresolved.

              • Re: SwiftUI and CoreData
                RΔSΞC Level 1 Level 1 (0 points)

                I did create  a simple project to show how to connect Core Data when presenting modally a view.

                https://github.com/R4S3CDev/CoreData_Integration

                • Re: SwiftUI and CoreData
                  bcalkin2 Level 1 Level 1 (0 points)

                  I'm seeing this error in XCode 11 GM seed 1 also. If I access the @FetchRequest in my root View it returns data correctly. If I try to use the same fetch is a child view I get: [SwiftUI] Context in environment is not connected to a persistent store coordinator: <NSManagedObjectContext: 0x2827ac460>.

                   

                  It is like the Environment losses the MOC relationship to the persistent store coordinator in the child views.

                   

                  I think I found a solution for the above issue. I needed to pass the MOC to the child view by adding it to the environment of that view. This allows the FetchRequest in child View (ProspectSelection) to return and not give the above error.

                  ProspectSelection(userData: self.userData, onDismiss: {
                                          self.showingSearchCriteria = false
                                          self.setModelViewData()
                                      }).environment(\.managedObjectContext, CoreDataStack.shared.persistentContainer.viewContext)
                  

                   

                  I thought the purpose the an EnvironmentObject is to safely allow every View to access an Object and not passed around. This does not seem to be working correctly. I may file a bug.

                   

                  For now I'll have to put the MOC in the enviroment of every View that needs a @FetchRequest.

                    • Re: SwiftUI and CoreData
                      Sir Spiff Level 1 Level 1 (0 points)

                      Thx , bcalkin2 you really made my day!!

                       

                      (Xcode Version 11.1 (11A1027))

                       

                      Here is how I did it (as a rookie I am, it took a while to decode what you really did ) (see bold text)

                       

                      Extra: - I´m also using  .background(EmptyView().sheet(is...... to allow the HomeView to have more than one modal sheet to pop up...

                       

                      import SwiftUI

                       

                      struct HomeView: View {

                          @State private var showUserListView = true

                          @State private var showRegisterNewUserView = false

                       

                          @ObservedObject var userValidation = UserValidationModel()

                       

                          var body: some View {

                              ZStack {

                                  Color(.darkGray).edgesIgnoringSafeArea(.all)

                                  VStack {

                                     Spacer()

                               

                                      Text("Main Screen").font(.largeTitle)

                       

                                      Button(action: {self.showRegisterNewUserView = true}) { Text("RegisterNewUser")}

                                      Button(action: {self.showUserListView = true}) { Text("showUserListView")}

                       

                                      Spacer()

                                  }

                              }

                              .background(EmptyView().sheet(isPresented: $showUserListView) {

                                  UserListView ()

                                  .environment(\.managedObjectContext, (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext)

                              })

                                .background(EmptyView().sheet(isPresented: $showRegisterNewUserView)

                                  RegisterNewUserView()

                                 .environment(\.managedObjectContext, (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext)

                              })

                       

                          }

                      }

                       

                      struct ContentView_Previews: PreviewProvider {

                          static var previews: some View {

                              HomeView()

                          }

                      }