首页 文章

RxSwift和MVVM:observable在没有绑定的情况下不执行

提问于
浏览
0

我是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 { $0.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 { $0.error }
        .filterNil()
}

}

我在视图控制器中有以下binginds:

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)

但是,如果我评论绑定,部分数据库更新将停止执行 . 无论如何我都需要让它执行,而不需要在视图模型中使用dispose bag . 可能吗?

还有一点额外的问题:我应该在我的视图模型代码中使用弱强舞 api / databasereturn Observable.empty() ,还是我可以安全地使用 unowned api / unowned database

谢谢 .

UPD:

APIService中返回observable的函数:

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: $0) })
}

1 回答

  • 1

    除非有订户准备接收结果,否则工作无法完成 .

    您的DatabaseService需要有一个dispose包并订阅 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.categoriesUpdateddatabase.updateObservable(with: requestResult.map { $0.element }.filterNil())

相关问题