在MVVM的架构模式下,RxSwift可以很方便的实现双向绑定。(View -> VM -> View)
当前实现需求: 搜索框输入关键字 -> 网络请求搜索数据 -> tableview加载数据
思路:搜索框绑定一个BehaviorSubject(观察者), BehaviorSubject(序列)通过高阶函数转换搜索结果为新序列, 搜索结果绑定tableview
// 双向绑定
searchBar.rx.text.orEmpty
.bind(to: viewModel.searchTextOB)
.disposed(by: disposeBag)
viewModel.searchData.drive(tableView.rx.items) { tb, indexPath, model -> LGTableViewCell in
let cell = tb.dequeueReusableCell(withIdentifier: self.resuseID) as! LGTableViewCell
cell.nameLabel.text = model.name
cell.classLabel.text = model.url
cell.selectionStyle = .none
return cell
}.disposed(by: disposeBag)
VM中的业务处理
class LGComprehensiveViewModel: NSObject {
let searchTextOB = BehaviorSubject(value: "")//既是序列也是观察者
//搜索的关键字作为序列 被搜索请求所订阅,有关键字变化时就会触发新的搜索
lazy var searchData: Driver<[LGReposityModel]> = {
return self.searchTextOB.asObservable()
.throttle(RxTimeInterval.milliseconds(300), scheduler: MainScheduler.instance)
.distinctUntilChanged()
.flatMapLatest(LGComprehensiveViewModel.reponseData)
.asDriver(onErrorJustReturn: [])
}()
static func reponseData(_ githubID: String) -> Observable<[LGReposityModel]> {
guard !githubID.isEmpty, let url = URL(string: "https://api.github.com/users/\(githubID)/repos") else {
return Observable.just([])
}
return URLSession.shared.rx.json(url: url)
.retry()
.observe(on: ConcurrentDispatchQueueScheduler(qos: .background))
.map(LGComprehensiveViewModel.dataParse)//序列化
}
static func dataParse(_ json: Any) -> [LGReposityModel] {
guard let items = json as? [[String: Any]] else { return [] }
guard let result = [LGReposityModel].deserialize(from: items) else { return [] }
return result as! [LGReposityModel]
}
}