我有以下设置,我想根据可以输入文本字段的用户名从GitHub API加载GitHub用户。
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
}
}
所以,我相信这个设置很标准。到目前为止一切运作良好,repositoriesButton
isEnabled
- 属性只有在找到所提供用户名的true
时才设置为User
。
但是,我还希望在网络请求进行时为activityIndicator
设置动画。理想情况下,我还希望使用isAnimating
绑定它的bindTo
属性。但是,这不起作用,因为根据maybeUserObservable
,我获得的唯一用于绑定的信息是是否返回了User
。因此,这与说明网络请求是否正在进行并不相同。
那么,我怎样才能确保activityIndicator.isAnimating
在网络请求开始时设置为true
,并在返回时false
设置为User
,无论是{{1}实际上是否已经退回?