RxSwift记录

在一个ViewModel里面有一个data属性,类型为Driver<[Repository]>,它用于发起网络请求,代码如下:

struct ViewModel {
    
    let searchText = Variable("")
    let disposeBag = DisposeBag()
    
    lazy var data: Driver<[Repository]> = {
        return self.searchText.asObservable()
            .throttle(0.3, scheduler: MainScheduler.instance)
            .distinctUntilChanged()
            .flatMapLatest {
                self.getRepositories($0)
            }
            .asDriver(onErrorJustReturn: [])
    }()
    
    ....
}
  • 在 ViewController 里把 UISearchBar 和 searchText 进行绑定,然后通过 data 和 UITableView 进行绑定,当 SearchBar 的 text 发现改变就触发网络请求,self.getRepositories($0),返回一个Observable<[Repository]>
    func getRepositories(gitHubID: String) -> Observable<[Repository]> {
        guard !gitHubID.isEmpty,
            let url = NSURL(string: "https://api.github.com/users/\(gitHubID)/repos")
            else { return Observable.just([]) }
        
        return NSURLSession.sharedSession()
            .rx_JSON(NSURLRequest(URL: url))
            .debug()
            .retry(3)
         // .catchErrorJustReturn([])
            .map {
                var repositories = [Repository]()
                
                if let items = $0 as? [[String: AnyObject]] {
                    items.forEach {
                        guard let name = $0["name"] as? String,
                            url = $0["html_url"] as? String
                            else { return }
                        repositories.append(Repository(name: name, url: url))
                    }
                }
                
                return repositories
        }
    }

但是这里会有一个问题,如果 rx_JSON 这里发射出一个Error,会导致data这个事件流后面被 dispose 了,然后后面在 SearchBar 中输入任何内容都不会执行, 可以在 retry 后面加上 .catchErrorJustReturn([]) 当遇到错误的时候返回 [], 当发生Error 的时候,不发射出 Error,而是发射出一个 [],所以当出现错误的时候,最终data的事件流中,不会出现Error事件,如果出现 Error 事件的时候被返回了 [],如果没有加 .catchErrorJustReturn([])的情况下,会导致 data 的事件流中接收到 Error,导致事件流被 dispose 了。

你可能感兴趣的:(RxSwift记录)