0

I'm trying to create an CoreData Entity observer:

@FetchRequest(sortDescriptors: []) var todoResult: FetchedResults<Todo>
    
    init() {
        todoResult.publisher.sink { _ in
            print("sink")
        } receiveValue: { todos in
            print("recoved todos")
        }.store(in: &cancellables)
}

But I'm getting this error:

Accessing StateObject's object without being installed on a View. This will create a new instance each time.

enter image description here

Any of you knows why I'm getting this error since I'm not creating this instance in a model? or if you know a work around this error. I'll really appreciated.

3
  • Why are you trying to set a publisher to a CoreData Entitywhich is already an ObservableObject? That is the root of your error message. Commented Apr 1, 2022 at 1:20
  • The behavior of FetchRequest is the same as State and StateObject, their internal are absent at initialisation phase and become available only inside body. To do what you want you can instantiate FetchRequest manually, like in stackoverflow.com/a/60761630/12299030 or in stackoverflow.com/a/59169794/12299030. Alternate is to create subview in body with injected todoResult, so todoResult will be already fetched and valid in that subview init. Commented Apr 1, 2022 at 6:19
  • All CoreData objects are ObservableObjects, just wrap each Todo in @ObservedObject in the SwiftUI View that needs/makes the changes. BTW it looks like you are trying to use @FetchRequest in a class` use NSFetchRequest or NSFetchedResultsController. Commented Apr 3, 2022 at 22:54

1 Answer 1

1

You have to use @FetchRequest inside a View struct.

The reason for the error that @StateObject must also be used inside a View struct is because the FetchRequest struct declares an @StateObject inside it, which is the delegate for the NSFetchedResultsController it uses.

In SwiftUI these dynamic properties/property wrappers give reference type semantics to the View struct value types so you don't need to use actual objects. SwiftUI calls update on these dynamic properties before body is run, which is how FetchRequest can retrieve the managed object context from the environment.

Also FYI when we do create an ObservableObject it's usually to hold our model struct array. If we use Combine inside one then we never use sink or cancellables, instead we assign the end of the pipeline to an @Published.

Sign up to request clarification or add additional context in comments.

1 Comment

I add it @Published internal var todo:[Todo] = [] and this todoResult.publisher.assign(to: \.todo, on: self).store(in: &cancellables) in the init but I'm getting this error Key path value type '[Todo]' cannot be converted to contextual type 'Publishers.Sequence<FetchedResults<Todo>, Never>.Output' (aka 'Todo')

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.