1

Rx ベースのネットワーク コードにユーザー主導の更新を実装しようとしています。現在の設計は次のとおりです。

  1. Voidユーザーが更新アクションを開始するたびに値が渡されるシンクを作成する
  2. flatMapそのシンクの最新の.NextイベントがObservable新しいネットワーク呼び出しに
  3. ネットワーク応答を新しいビュー モデルに変換し、それをビュー コントローラーに戻します。

私が夢中になっている部分は、これらのイベントがダウンするためのシンクを作成する方法です。私の現在のコードは次のとおりです。

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

4

0 に答える 0