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之前不会重新分配。此外,如果多次订阅此 observable,refreshSink则将重新分配该变量。

所以我的问题是:我如何创建一个Observable可以手动下推事件的?或者,我可以在这里使用更好的设计吗?

我知道 ReactiveCocoa 有一个pipe静态方法,Signal它会做一些我正在寻找的事情,但我在 Rx API 中没有找到等价物。

4

0 回答 0