tonytran
tonytran

Reputation: 1078

onCompleted never gets called

By using RxSwift, the purpose of my project is whenever an user types a city in search bar, it will make a call to wrap the current temperature. Currently, I have viewModel which contains

var searchingTerm = Variable<String>("") // this will be binded to search text from view controller
var result: Observable<Weather>!         // this Observable will emit the result based on searchingTerm above.

In api service, I'm wrapping a network call using RxSwift by following

func openWeatherMapBy(city: String) -> Observable<Weather> {
    let url =   NSURL(string: resourceURL.forecast.path.stringByReplacingOccurrencesOfString("EnterYourCity", withString: city))

    return Observable<WeatherModel>.create({ observer -> Disposable in
        let downloadTask    =   self.session.dataTaskWithURL(url!, completionHandler: { (data, response, error) in
            if let err = error {
                observer.onError(err)
            }
            else {
                do {
                    let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments) as! [String: AnyObject]

                    let weather = Weather(data: json)
                    observer.onNext(weather) 
                    observer.onCompleted()
                }
                catch {

                }

            }
        })

        downloadTask.resume()

        return AnonymousDisposable {
            downloadTask.cancel()
        }
    })
}

As long as the model created, I'll send it to an observer and complete

At view controller, I'm doing

viewModel.result
            .subscribe( onNext:     { [weak self] model  in
                            self?.weatherModel = model
                            dispatch_async(dispatch_get_main_queue(), { 
                                self?.cityLabel.text        = model.cityName
                                self?.temperatureLabel.text = model.cityTemp?.description
                            })

                        },
                        onError:    { (error) in
                            print("Error is \(error)")
                        },
                        onCompleted:{
                            print("Complete")
                        }
                      )
                            { print("Dealloc")}
            .addDisposableTo(disposeBag)
    }

It works as expected, UI is updated and show me what I want. However, I have just realized that onCompleted never gets called. I assume if I do everything right, I must have it printed out.

Any ideas about this issue. All comments are welcomed here.

Upvotes: 1

Views: 2856

Answers (1)

tomahh
tomahh

Reputation: 13651

result seems to be derived from searchingTerm, which is a Variable.

Variable only complete when they are being deallocated (source) so it makes sense that result does not receive onCompleted.

It makes sense that the behavior is this one. An observable will never emit new values after onCompleted. And you don't want it to stop updating after the first search result is presented.

Upvotes: 3

Related Questions