Reputation: 1078
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
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