Rx ベースのネットワーク コードにユーザー主導の更新を実装しようとしています。現在の設計は次のとおりです。
Void
ユーザーが更新アクションを開始するたびに値が渡されるシンクを作成するflatMap
そのシンクの最新の.Next
イベントがObservable
新しいネットワーク呼び出しに- ネットワーク応答を新しいビュー モデルに変換し、それをビュー コントローラーに戻します。
私が夢中になっている部分は、これらのイベントがダウンするためのシンクを作成する方法です。私の現在のコードは次のとおりです。
func contactListModel() -> Observable<ContactListViewModel<Contact>> {
// Create a sink for refresh events
var refreshSink: AnyObserver<Void> = AnyObserver { event in }
let refreshObservable = Observable<Void>.create { observer in
refreshSink = observer
return NopDisposable.instance
}
// Define action handlers
let searchClosure = { (query: String?) in
self.contactsSearchTerm.value = query
}
let refreshClosure = refreshSink.onNext
// TODO: [RP] Make contact list view controller handle a nil view model to remove the need for this code
let initialViewModel = ContactListViewModel<Contact>(contacts: [], searchClosure: searchClosure, refreshClosure: refreshClosure)
// Perform an initial refresh
defer {
refreshSink.onNext()
}
// Set up subscription to push a new view model each refresh
return refreshObservable
.flatMapLatest {
return self.networking.request(.ListContacts)
}
.mapToObject(ListContactsResponse)
.map { response in
return ContactListViewModel(contacts: response.contacts, searchClosure: searchClosure, refreshClosure: refreshClosure)
}
.startWith(initialViewModel)
}
これで、イベント シンクを作成するコードがここで機能しない理由が明らかになりました。refreshObservable
のメソッドに渡されるブロックcreate
は、オブザーバーがサブスクライブされると呼び出されるため、refreshSink
それまでは再割り当てされません。さらに、このオブザーバブルが複数回サブスクライブされている場合、refreshSink
変数は再割り当てされます。
だから私の質問はこれです:イベントを手動でプッシュできるを作成するにはどうすればよいですか? Observable
または、ここで使用できるより良いデザインはありますか?
ReactiveCocoa には、私が探しているようなことを行うpipe
静的メソッド onがあることは知っていますが、Rx API には同等のものが見つかりませんでした。Signal