1

I have the following setup, where I want to load a GitHub user from the GitHub API based on the username that can be typed into a text field.

class SearchUserViewController: UIViewController {

  @IBOutlet weak var nameTextField: UITextField!
  @IBOutlet weak var activityIndicator: UIActivityIndicatorView!
  @IBOutlet weak var repositoriesButton: UIButton!

  let httpClient = HTTPClient()
  let disposeBag = DisposeBag()

  override func viewDidLoad() {
    super.viewDidLoad()
    repositoriesButton.isEnabled = false
    activityIndicator.hidesWhenStopped = true

    setupUserObservable()
  }

 func setupUserObservable() {

    let maybeUserObservable: Observable<User?>= nameTextField.rx.text
      .throttle(0.5, scheduler: MainScheduler.instance)
      .flatMapLatest { query in
        self.fetchUser(username: query!)
          .observeOn(MainScheduler.instance) 
          .catchErrorJustReturn(nil) 
      }

    // bind button enabled property
    maybeUserObservable
      .map { return $0 != nil }
      .bindTo(repositoriesButton.rx.isEnabled)
      .addDisposableTo(disposeBag)

  }

  func fetchUser(username: String) -> Observable<User?> {

    let url = httpClient.searchUserURL(for: username)!
    let jsonObservable = URLSession.shared.rx.json(url: url)

    let userObservable: Observable<User?> = jsonObservable.map { (json: Any) -> [String: Any]? in
      guard let userInfo = json as? [String: Any] else {
        return nil
      }
      return userInfo
      }.map { (maybeUserInfo: [String: Any]?) -> User? in
        guard let userInfo = maybeUserInfo else {
          return nil
        }
        return self.httpClient.jsonToOptionalUser(userInfo: userInfo)
    }
    return userObservable
  }

}

So, the setup is pretty standard I believe. It all works well so far, the repositoriesButton's isEnabled-property is only set to true if a User was found for the provided username.

However, I also would like to animate the activityIndicator when a network request is going on. Ideally, I would also like to bind it's isAnimating property using bindTo. However, that doesn't work because the only info I get that I cam use for bindings based on the maybeUserObservable is whether a User was returned or not. So, this is not the same as saying whether a network request is ongoing or not.

So, how can I make sure that activityIndicator.isAnimating is set to true whenever a network request is started and to false as soon as it returns - no matter whether a User was actually returned or not?

nburk
  • 22,409
  • 18
  • 87
  • 132
  • using ActivityIndicator solves the issue https://github.com/ReactiveX/RxSwift/blob/83bac6db0cd4f7dd3e706afc6747bd5797ea16ff/RxExample/RxExample/Services/ActivityIndicator.swift – nburk Nov 17 '16 at 22:31

0 Answers0