私はRxSwiftを初めて使い、MVVMアーキテクチャを使ってアプリケーションを実装しようとしています。私は、ビューモデルがあります: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
/database
とreturn Observable.empty()
で弱い強いダンスを使うべきか、私は無事unowned api
/unowned database
を使用することができますか?
ありがとうございました。
UPD:APIServiceで観察復帰のための
機能:結果を受け取るために用意した加入者がある場合を除き
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) })
}
ありがとう!しかし、サブスクライブで「弱い自己」の代わりに「無所属の自己」を使うことはできますか? 'self'によって所有されている' disposeBag'を購読することは、 'self'初期化の後に呼び出すことはできませんが、わかりません。または、ブロックの実行を開始し、バックグラウンドで作業を保存し、 'self?_ categories.onNext()'に到達することができます。 –
プログラムの終了時に自己が存在することがわかっている場合にのみ 'unowned'を使います。サブスクライブは一度だけ呼び出されるか、サブスクライブクローズは' self'が削除される何かをしていることを知っています。弱いところで、あなたは 'APIService'で上記を行うこともできます。そうすれば、あなたのビューモデルにはロジックだけが含まれます。 –
apiサービスで 'actionRequest'を購読し、データベースの例のように、基礎となるサブジェクトからオブジェクトを返すべきですか?しかし、私は監視可能な戻り値を持つ汎用関数を持っています(更新された答えを参照してください)、 'APIService'の同じインスタンスから別の戻り値の型を持つ2つの要求を行うとどうなるかは分かりません –