我这样提取core data
:
var persistingData: [MyDataObject] = coreData.fetchAll(fetchRequest: NSFetchRequest<MyDataObject>(entityName: "MyDataObject"))
现在如何将这些数据用于Observable
,可以将bind
数据转换为rx
tableView
?
我是否创建像这样的observable
:
func fetchAllData() -> Observable<[MyDataObject]> {
var persistingData: [MyDataObject] = coreData.fetchAll(fetchRequest: NSFetchRequest<MyDataObject>(entityName: "MyDataObject"))
return Observable.create({ observable in
observable.onNext(persistingData)
observable.onCompleted()
return Disposables.create()
})
}
但是如果我将数据传递给bind()
,该如何在observable
上使用onNext
?像这样直接在bind
上使用method
:
fetchAllData().bind()
我实际上如何将data
放入observable
,以便可以在bind()
中使用?
EDIT
我也尝试过这种方法。这是一种有效的方法吗?
func fetchAllData() -> PublishRelay<[MyDataObject]> {
var persistingData: [MyDataObject] = coreData.fetchAll(fetchRequest: NSFetchRequest<MyDataObject>(entityName: "MyDataObject"))
let relay = PublishRelay<[LocalDoorCoreDataObject]>()
relay.accept(persistingDoors)
return relay
}
然后您可以像这样bind
:
viewModel.fetchAllData().bind(to: tableView.rx.items(cellIdentifier: Cell.identifier, cellType: Cell.self)) { row, data, cell in
cell.viewModel = data
}.disposed(by: disposeBag)
这似乎合理,还是有其他方法?
Rx在处理数据流时特别有用,但是您尝试将其用作单个核心数据获取请求的简单包装。我将构建一个BehaviorRelay
以保留来自Core Data的数据的副本,以及一个Observable,该Observable运行您的提取请求并向BehaviorRelay
报告值,您可以在需要刷新的任何时间对其进行订阅。
具有您的视图模型:
let data = BehaviorRelay<[MyDataObject]>(value: [])
我将其绑定到您的表视图:
viewModel.data.bind(to: tableView.rx.items(cellIdentifier: Cell.identifier, cellType: Cell.self)) { row, data, cell in
cell.viewModel = data
}.disposed(by: disposeBag)
然后返回您的视图模型:
var loadData: Observable<[MyDataObject]> {
return Observable.deferred { [unowned self] in
return Observable.just(self.coreData.fetchAll(fetchRequest: NSFetchRequest<MyDataObject>(entityName: "MyDataObject")))
}.do(onNext: { [unowned self] data in
self.data.accept(data)
}
}
每当您需要刷新数据时,您只需致电:
viewModel.loadData.subscribe().disposed(by: disposeBag)
您可以使用loadData
发出的值来立即更改UI,例如显示空白屏幕或停止加载指示器。如果您这样做,请确保在订阅前添加observeOn(MainScheduler.instance)
。
让我们开始获取。
func fetchAllData() -> Observable<[MyDataObject]> {
Observable.just(coreData.fetchAll(fetchRequest: NSFetchRequest<MyDataObject>(entityName: "MyDataObject")))
}
(上面的操作与fetchAllData所做的相同,但更简洁。)
现在考虑所有可能要获取数据的原因...假设您有一个刷新按钮,而只有当用户点击该按钮时,您才想获取所有数据。然后,在您的viewDidLoad
(或从中调用的函数)中,您将拥有:
let allData = refreshButton.rx.tap
.flatMap {
fetchAllData()
}
假设我们要在表格视图上显示数据。我们要在视图上重新加载数据的所有原因是什么?假设我们要重新加载数据的唯一原因是allData
发出值时。然后,在viewDidLoad
(或从中调用的函数)中,您还将具有:
allData
.bind(to: tableView.rx.items(cellIdentifier: Cell.identifier, cellType: Cell.self)) { row, data, cell in
cell.viewModel = data
}
.disposed(by: disposeBag)
我们走了,就这么简单。
现在,当您预想其他时候可能想要获取所有数据时,事情将会变得更加复杂,但是以上是基础知识。