RxSwift 和 MVVM:可观察的不执行不绑定
RxSwift and MVVM: observable not executing without binding
我是 RxSwift 的新手,正在尝试使用 MVVM 架构实现应用程序。我有视图模型:
class CategoriesViewModel {
fileprivate let api: APIService
fileprivate let database: DatabaseService
let categories: Results<Category>
// Input
let actionRequest = PublishSubject<Void>()
// Output
let changeset: Observable<(AnyRealmCollection<Category>, RealmChangeset?)>
let apiSuccess: Observable<Void>
let apiFailure: Observable<Error>
init(api: APIService, database: DatabaseService) {
self.api = api
self.database = database
categories = database.realm.objects(Category.self).sorted(byKeyPath: Category.KeyPath.name)
changeset = Observable.changeset(from: categories)
let requestResult = actionRequest
.flatMapLatest { [weak api] _ -> Observable<Event<[Category]>> in
guard let strongAPI = api else {
return Observable.empty()
}
let request = APIService.MappableRequest(Category.self, resource: .categories)
return strongAPI.mappedArrayObservable(from: request).materialize()
}
.shareReplayLatestWhileConnected()
apiSuccess = requestResult
.map { [=10=].element }
.filterNil()
.flatMapLatest { [weak database] newObjects -> Observable<Void> in
guard let strongDatabase = database else {
return Observable.empty()
}
return strongDatabase.updateObservable(with: newObjects)
}
apiFailure = requestResult
.map { [=10=].error }
.filterNil()
}
}
我在视图控制器中有以下 bininds:
viewModel.apiSuccess
.map { _ in false }
.bind(to: refreshControl.rx.isRefreshing)
.disposed(by: disposeBag)
viewModel.apiFailure
.map { _ in false }
.bind(to: refreshControl.rx.isRefreshing)
.disposed(by: disposeBag)
但是如果我评论绑定,数据库更新部分将停止执行。无论如何我都需要让它执行,而不是在视图模型中使用处理包。可能吗?
还有一个小问题:我应该像在我的视图模型代码中那样使用 api
/database
和 return Observable.empty()
的弱-强舞蹈,还是可以只使用 unowned api
/unowned database
安全吗?
谢谢。
更新:
在 APIService 中可观察到的 return 函数:
func mappedArrayObservable<T>(from request: MappableRequest<T>) -> Observable<[T]> {
let jsonArray = SessionManager.jsonArrayObservable(with: request.urlRequest, isSecured: request.isSecured)
return jsonArray.mapResponse(on: mappingSheduler, { Mapper<T>().mapArray(JSONArray: [=12=]) })
}
除非有订阅者准备接收结果,否则工作不会完成。
您的 DatabaseService 需要有一个处理包并订阅 Observable<[Category]>
。类似于:
class ProductionDatabase: DatabaseService {
var categoriesUpdated: Observable<Void> { return _categories }
func updateObservable(with categories: Observable<[Category]>) {
categories
.subscribe(onNext: { [weak self] categories in
// store categories an then
self?._categories.onNext()
})
.disposed(by: bag)
}
private let _categories = PublishSubject<Void>()
private let bag = DisposeBag()
}
然后 apiSuccess = database.categoriesUpdated
和 database.updateObservable(with: requestResult.map { [=13=].element }.filterNil())
我是 RxSwift 的新手,正在尝试使用 MVVM 架构实现应用程序。我有视图模型:
class CategoriesViewModel {
fileprivate let api: APIService
fileprivate let database: DatabaseService
let categories: Results<Category>
// Input
let actionRequest = PublishSubject<Void>()
// Output
let changeset: Observable<(AnyRealmCollection<Category>, RealmChangeset?)>
let apiSuccess: Observable<Void>
let apiFailure: Observable<Error>
init(api: APIService, database: DatabaseService) {
self.api = api
self.database = database
categories = database.realm.objects(Category.self).sorted(byKeyPath: Category.KeyPath.name)
changeset = Observable.changeset(from: categories)
let requestResult = actionRequest
.flatMapLatest { [weak api] _ -> Observable<Event<[Category]>> in
guard let strongAPI = api else {
return Observable.empty()
}
let request = APIService.MappableRequest(Category.self, resource: .categories)
return strongAPI.mappedArrayObservable(from: request).materialize()
}
.shareReplayLatestWhileConnected()
apiSuccess = requestResult
.map { [=10=].element }
.filterNil()
.flatMapLatest { [weak database] newObjects -> Observable<Void> in
guard let strongDatabase = database else {
return Observable.empty()
}
return strongDatabase.updateObservable(with: newObjects)
}
apiFailure = requestResult
.map { [=10=].error }
.filterNil()
}
}
我在视图控制器中有以下 bininds:
viewModel.apiSuccess
.map { _ in false }
.bind(to: refreshControl.rx.isRefreshing)
.disposed(by: disposeBag)
viewModel.apiFailure
.map { _ in false }
.bind(to: refreshControl.rx.isRefreshing)
.disposed(by: disposeBag)
但是如果我评论绑定,数据库更新部分将停止执行。无论如何我都需要让它执行,而不是在视图模型中使用处理包。可能吗?
还有一个小问题:我应该像在我的视图模型代码中那样使用 api
/database
和 return Observable.empty()
的弱-强舞蹈,还是可以只使用 unowned api
/unowned database
安全吗?
谢谢。
更新:
在 APIService 中可观察到的 return 函数:
func mappedArrayObservable<T>(from request: MappableRequest<T>) -> Observable<[T]> {
let jsonArray = SessionManager.jsonArrayObservable(with: request.urlRequest, isSecured: request.isSecured)
return jsonArray.mapResponse(on: mappingSheduler, { Mapper<T>().mapArray(JSONArray: [=12=]) })
}
除非有订阅者准备接收结果,否则工作不会完成。
您的 DatabaseService 需要有一个处理包并订阅 Observable<[Category]>
。类似于:
class ProductionDatabase: DatabaseService {
var categoriesUpdated: Observable<Void> { return _categories }
func updateObservable(with categories: Observable<[Category]>) {
categories
.subscribe(onNext: { [weak self] categories in
// store categories an then
self?._categories.onNext()
})
.disposed(by: bag)
}
private let _categories = PublishSubject<Void>()
private let bag = DisposeBag()
}
然后 apiSuccess = database.categoriesUpdated
和 database.updateObservable(with: requestResult.map { [=13=].element }.filterNil())