ReactiveSwift: наблюдайте за изменениями управляемого объекта с помощью MutableProperty - PullRequest
3 голосов
/ 29 апреля 2019

Мой проект имеет CoreData базу данных с 1 корневым контекстом и несколькими подконтекстами. У меня есть ViewModel, который содержит предмет (NSManagedObject). Когда я изменяю что-то в Item, постоянство создается в корневом контексте, а затем автоматически объединяется со всеми подконтекстами.

Я хочу заменить NSFetchedResultsController на ReactiveSwift Сигналы / Свойства, чтобы наблюдать изменения в объекте предмета.

ViewModel:

var itemProperty: MutableProperty<Item> = MutableProperty(contextItem)

ViewController:

self.viewModel.itemProperty.signal.observeValues{ (item: Item) in
     let newName = item.name
     print("name: \(newName!)" 
 }

После того, как я изменяю имя элемента где-то еще, изменения распространяются в под-контекст ViewModel (уведомление получает NSFetchedResultsController), НО сигнал никогда не выдвигает новое событие item.

Может быть, потому что ссылка NSManagedObject никогда не меняется? Я знаю, что могу наблюдать изменения определенных свойств объекта с producer(forKeyPath: "propertyKeyPath" ), но я не хочу наблюдать только одно конкретное свойство элемента, я хочу наблюдать ВСЕ изменения.

Есть ли способ наблюдать ЛЮБОЕ изменение всех свойств объекта?

Ответы [ 2 ]

0 голосов
/ 18 июня 2019

Итак, после небольшого исследования я обнаружил, что ReactiveCocoa не так хорошо подготовлен для работы с Core Data.Невозможно получать обновления NSManagedObject только с помощью ReactiveCocoa / ReactiveSwift.

Одной из опций может быть обновление ItemProperty при каждом обновлении из NSFetchedResultsController и запуск нового события в связанном сигнале свойства:

var entityProperty: MutableProperty<MyEntity>

override func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) 
{
    entityProperty.value = anObject as! MyEntity
}

Другим вариантом может быть получение сигнала об обновлениях определенных свойств в моем объекте:

var myEntity: MyEntity

// ReactiveObjectiveC
myEntity.rac_values(forKeyPath: "name", observer: self)

// ReactiveSwift
myEntity.reactive.signal(forKeyPath: "name")
0 голосов
/ 30 апреля 2019

Вы могли наблюдать NSManagedObjectContextObjectsDidChange. Это может быть несколько излишним, потому что он отправляет уведомление, когда любое изменение происходит на любых объектов. Но я использовал его без какого-либо заметного снижения производительности Вот документация Apple .

Главный недостаток NSManagedObjectContextObjectsDidChange заключается в том, что он не дает вам измененные ключи или значения. Если вам это нужно, осознайте, что создание наблюдателей для всех свойств может быть не таким обременительным, как вы думаете. Это можно сделать в одном цикле, итерируя по NSEntityDescription.properties или одному из четырех других похожих свойств, перечисленных в нижней части его документации .

...