1

I've been working on a search controller that is using RxSwift to update DataSource when user types in Search field, like it's described here: http://www.thedroidsonroids.com/blog/ios/rxswift-examples-3-networking/

That is my viewmodel:

struct SearchControllerViewModel {

    let provider: RxMoyaProvider<ThreadifyEndpoint>
    let startsWith: Observable<String>

    func startSearching() -> Observable<[SearchedNodeViewModel]> {
        return startsWith
            .observeOn(MainScheduler.instance)
            .flatMapLatest { query -> Observable<[SearchedNodeViewModel]?> in
                return self.findNodes(query)
        }.replaceNilWith([])


    }

    internal func findNodes(startsWith: String) -> Observable<[SearchedNodeViewModel]?> {
        return self.provider
            .request(ThreadifyEndpoint.SearchForNodes(startsWith: startsWith))
            .mapArrayOptional(SearchedNodeViewModel.self)
    }
}

Now I want new data to be loaded not only when user is typing but either when sh's scrolling down. I was thinking to use combineLatest to observe both rx_text and rx_offset but I can't pass Observable to combineLatest because of compilation error.

solidcell
  • 7,639
  • 4
  • 40
  • 59
alexxjk
  • 1,681
  • 5
  • 18
  • 30
  • What's the compilation error? combineLatest takes multiple Observables, so that's odd. – solidcell May 07 '16 at 12:04
  • @solidcell Cannot invoke 'combineLatest' with an argument list of type (Observable, Observable) – alexxjk May 08 '16 at 14:01
  • I've answered below. Also, if you tag your Swift questions with a `swift` tag, your questions (and the answers) will get syntax highlighting. – solidcell May 09 '16 at 10:31

1 Answers1

2

The compilation error you're seeing is due to you not using an actual method. The method signature you're intending to use is:

public class func combineLatest<O1 : ObservableType, O2 : ObservableType>(source1: O1, _ source2: O2, resultSelector: (O1.E, O2.E) throws -> Element) -> RxSwift.Observable<Element>

Notice that there's a third argument that you're forgetting: resultSelector. That's supposed to be a block that describes how you want to combine the latest elements into a new element.

Based on your error message, I'm thinking you're using it like this:

let combined = Observable.combineLatest(stringObservable, pointObservable)

Whereas, you should be using it like this:

let combined = Observable.combineLatest(stringObservable, pointObservable) { (s, p) in
    return "\(s), \(p)" // or construct your new element however you'd like
}

Without the block, RxSwift doesn't know how you'd like to combine them. You might have been thinking it would just default to making a new tuple of (String, CGPoint) as the element, but it makes no such assumptions and requires you to tell it.

solidcell
  • 7,639
  • 4
  • 40
  • 59