Combine, Publishers, and Core Data
Create a continuous stream of information from Core Data to your UI

In my previous piece, RxSwift, Observables, and Core Data, I presented a way to get an observable directly out of your Core Data cache. But some are already using Apple's Combine framework, so I prepared exactly the same solution for Combine.
The general idea is to get a stream of Core Data entities in the form of a publisher and send new values each time those Core Data entities for the given FetchRequest are updated, inserted, or deleted.
I will not get into many details on how you can use this stream. More information can be found in my previous piece.
We will need NSFetchRequest
and a NSManagedObjectContext
to initialize the following publisher:
Every time Core Data is updated, the CDPublisher
sends new values to its subscriber.
I recommend not using the Core Data entity directly but converting it into a domain struct and using that.
Here’s an example for the Customer entity:

I would create the following struct:
struct DCustomer {
let id: Int
let name: String
let phone: String
}
And map the result of the CDPublisher
to that:
CDPublisher(request: Customer.fetchRequest(), context: database.viewContext)
.map { $0.map { DCustomer(id: $0.id, name: $0.name, phone $0.phone) } }
What to Do From Here
If you work with SwiftUI, you can update your ViewModel's Published
property.
Keep the following in mind here:
- When assigning to a
Published
property, receive the values in the main thread. - Do not use
.assign(to: \.customers, on: self)
because it causes a self-reference to self and your MyViewModel will never be deallocated. - Use
[weak self]
in the.sink
closure. - Better solutions exist that could replace this ugly
.map().recieve().sink().store()
, but that would be a topic for another piece.
As always, happy coding.