returns 来自异步完成处理程序的 RXSwift 平面图
RXSwift flatmap that returns from an async completion handler
我正在尝试创建一个 searchBar,它通过带有请求的 MKLocalSearch 搜索地址并使用 RXSwift 并绑定到 RXCocoa
到目前为止我已经完成了以下工作
1.过滤和去抖,避免请求过多:
let searchRes = searchBar.rx.text
.orEmpty
.filter { query in
return query.characters.count > 4
}
.debounce(1, scheduler: MainScheduler.instance)
生成的字符串查询是 map:ed 创建一个 MKLocationSearch,然后 flatMapp:ed 到 return 一个 MKMapItems 数组,以便能够将该数组绑定到 tableView 的项目:
searchRes.map{query -> MKLocalSearch in
let request = MKLocalSearchRequest()
request.naturalLanguageQuery = query
request.region = self.mapView.region
return MKLocalSearch(request: request)
}.flatMapLatest{search -> Observable<[MKMapItem]> in
search.start(completionHandler:{(response, error) in
let items: Variable<[MKMapItem]> = Variable([])
if let resp = response {
//need to return the result form this
// i.e. items.value = response.mapItems
}
//can not return from here since the request is async
}
}.bindTo //continue to bind to tableview
如何使用 RXSwift 完成此操作,我找不到任何相关示例
您必须使用异步请求创建一个 Observable。您可以定义以下方法来执行此操作:
func mapItems(for searchRequest: MKLocalSearch) -> Observable<[MKMapItem]> {
return Observable.create { observer in
searchRequest.start(completionHandler: { (response, error) in
if let error = error {
observer.onError(error)
} else {
let items = response?.mapItems ?? []
observer.onNext(items)
observer.onCompleted()
}
})
return Disposables.create {
searchRequest.cancel()
}
}
}
然后你可以使用 flatMapLatest
和那个方法:
searchRes
.map { query -> MKLocalSearch in
let request = MKLocalSearchRequest()
request.naturalLanguageQuery = query
request.region = self.mapView.region
return MKLocalSearch(request: request)
}
.flatMapLatest{ [unowned self] search -> Observable<[MKMapItem]> in
self.mapItems(for: search)
}
.bindTo(....
我正在尝试创建一个 searchBar,它通过带有请求的 MKLocalSearch 搜索地址并使用 RXSwift 并绑定到 RXCocoa
到目前为止我已经完成了以下工作 1.过滤和去抖,避免请求过多:
let searchRes = searchBar.rx.text
.orEmpty
.filter { query in
return query.characters.count > 4
}
.debounce(1, scheduler: MainScheduler.instance)
生成的字符串查询是 map:ed 创建一个 MKLocationSearch,然后 flatMapp:ed 到 return 一个 MKMapItems 数组,以便能够将该数组绑定到 tableView 的项目:
searchRes.map{query -> MKLocalSearch in let request = MKLocalSearchRequest() request.naturalLanguageQuery = query request.region = self.mapView.region return MKLocalSearch(request: request) }.flatMapLatest{search -> Observable<[MKMapItem]> in search.start(completionHandler:{(response, error) in let items: Variable<[MKMapItem]> = Variable([]) if let resp = response { //need to return the result form this // i.e. items.value = response.mapItems } //can not return from here since the request is async } }.bindTo //continue to bind to tableview
如何使用 RXSwift 完成此操作,我找不到任何相关示例
您必须使用异步请求创建一个 Observable。您可以定义以下方法来执行此操作:
func mapItems(for searchRequest: MKLocalSearch) -> Observable<[MKMapItem]> {
return Observable.create { observer in
searchRequest.start(completionHandler: { (response, error) in
if let error = error {
observer.onError(error)
} else {
let items = response?.mapItems ?? []
observer.onNext(items)
observer.onCompleted()
}
})
return Disposables.create {
searchRequest.cancel()
}
}
}
然后你可以使用 flatMapLatest
和那个方法:
searchRes
.map { query -> MKLocalSearch in
let request = MKLocalSearchRequest()
request.naturalLanguageQuery = query
request.region = self.mapView.region
return MKLocalSearch(request: request)
}
.flatMapLatest{ [unowned self] search -> Observable<[MKMapItem]> in
self.mapItems(for: search)
}
.bindTo(....