Создайте непрерывный поток информации из Core Data в ваш пользовательский интерфейс
В моей предыдущей статье RxSwift, Observables и Core Data я представил способ получить наблюдаемое непосредственно из вашего кэша Core Data. Но некоторые уже используют Apple Combine framework, поэтому я приготовил точно такое же решение для Combine.
Общая идея состоит в том, чтобы получить поток сущностей Core Data в форме издателя и отправлять новые значения каждый раз, когда эти сущности Core Data для данного FetchRequest обновляются, вставляются или удаляются.
Я не буду вдаваться в подробности того, как вы можете использовать этот поток. Более подробную информацию можно найти в моей предыдущей статье.
Нам понадобится NSFetchRequest
и NSManagedObjectContext
для инициализации следующего издателя:
Каждый раз, когда Core Data обновляется, CDPublisher
отправляет новые значения своему подписчику.
Я рекомендую не использовать сущность Core Data напрямую, а преобразовать ее в структуру домена и использовать ее.
Вот пример объекта "Клиент":
Я бы создал следующую структуру:
struct DCustomer { let id: Int let name: String let phone: String }
И сопоставьте результат CDPublisher
с этим:
CDPublisher(request: Customer.fetchRequest(), context: database.viewContext) .map { $0.map { DCustomer(id: $0.id, name: $0.name, phone $0.phone) } }
Что делать отсюда
Если вы работаете со SwiftUI, вы можете обновить свойство ViewModel Published
.
Имейте в виду следующее:
- При присвоении свойству
Published
значения получают в основном потоке. - Не используйте
.assign(to: \.customers, on: self)
, потому что это вызывает ссылку на себя, и ваша MyViewModel никогда не будет освобождена. - Используйте
[weak self]
в закрытии.sink
. - Существуют лучшие решения, которые могли бы заменить эту уродливую
.map().recieve().sink().store()
, но это тема для другой статьи.
Как всегда, удачного кодирования.