How to use NSFetchedResultsController with SwiftUI

CoreData is one of the frameworks I use quite often, and I can’t imagine using it without fetched results controller (FRC) because they are so powerful and yet easy to use. This demo will show you how to get and filter your core data objects using FRC.
Fetching data
We will add our FRC in our view model. To use FRC, our class has to conform to the NSFetchedResultsControllerDelegate protocol. To conform to the protocol, our view model needs to inherit NSObject class.
Look at the properties above. CoreDataBookService is a helper class that will provide us the fetch request and context to perform the request. This class will is responsible for everything regarding the Book object, which is the NSManagedObject.
As you can see, we use CoreDataManager inside of the CoreDataBookService. I call this approach “service-oriented architecture”. If you want to find out more about it, visit this link. CoreDataManagers stores NSPersistentContainer, and we create a main context using the container:
In the init method of the BooksViewModel, we will initialize FRC using bookServices’ booksFetchRequest and context. We won’t use caching or grouping data in the demo. After the initialization of FRC, we need to set its delegate and perform the first fetch. We store results in the books property. Whenever we add, edit or delete a book object, method controllerDidChangeContent will fire. Then we will set a new value to the books, and finally, the @Published property will update our SwiftUI view.
That’s it. Our view model is ready to fetch the data from the database.
Filtering data
If we want to add a search bar in our view and filter data, we can do it fairly quickly. We have to add new published property. We will bind it to some text field in the view. Whenever text changes, we will set up our FRC to perform the new fetch with the desired predicate.
We will update and rename the setupFetchResultsController method to setupFetchResultsPredicateAndFetch. We have to set the predicate if we have a search string and remove it otherwise. Now FRC will only show the results we need.
The view
Finally, we will create a simple view to demonstrate how to bind everything together. We will use a simple text field and a list. Don’t let method toBook() confuse you. I use it to transform a custom NSManagedObject into a more view-friendly model.
Conclusion
Using FRC with SwiftUI and combine is very straightforward. Even if we had a complex filtering system, we could create it easily by using bindings. The bottom line is if you use core data in your iOS app, you have to work with fetch results controllers. I hope this quick demo helped you get the basics.