使用 RxSwift 将 Alamofire 请求绑定到表视图
Posted
技术标签:
【中文标题】使用 RxSwift 将 Alamofire 请求绑定到表视图【英文标题】:Bind Alamofire request to table view using RxSwift 【发布时间】:2018-10-04 23:23:13 【问题描述】:所以我已经研究了几天 RxSwift,并试图用它创建一个简单的应用程序。我已将我的表的 searchController 绑定到结果,这些结果会输入到 cellForRowAt
函数中。如何将 alamofire 响应绑定到每个单元格?
我需要做哪些?
Variable
并使用 toObservable
?
绑定response
或searchResultsArray
以创建每个单元格。
我需要使用的函数是:
.bind(to: self.tableView.rx.items(cellIdentifier: "cell", cellType: UITableViewCell.self)) row, element, cell in
cell.textLabel?.text = "something"
这是我当前的 RxSwift 代码:
let disposeBag = DisposeBag()
var searchResultsArray = [[String:String]]()
searchController.searchBar.rx.text.orEmpty.filter text in
text.count >= 3
.subscribe(onNext: text in
searchRequest(search: text, searchType: "t:t") response in
self.searchResultsArray = response
self.tableView.reloadData()
).disposed(by: disposeBag)
这是我当前的单元格创建功能。当点击取消按钮时,showSearchResults
会发生变化。
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell: UITableViewCell =
guard let cell = tableView.dequeueReusableCell(withIdentifier: "cell") else
return UITableViewCell(style: .subtitle, reuseIdentifier: "cell")
return cell
()
if self.shouldShowSearchResults
cell.textLabel?.text = searchResultsArray[indexPath.row]["result"]!
cell.detailTextLabel?.text = searchResultsArray[indexPath.row]["location"]!
return cell
这是我当前的 api 请求:
func searchRequest(search: String, searchType: String, completionHandler: @escaping ([[String: String]]) -> ())
let payload: [String: Any] = [
"q": search,
"fq": searchType,
"start": 0
]
let url = URL(string: "https://www.athletic.net/Search.aspx/runSearch")!
Alamofire.request(url, method: .post, parameters: payload, encoding: JSONEncoding.default).responseJSON response in
let json = response.data
do
var searchResults: [[String: String]] = []
let parsedJson = JSON(json!)
if let doc = try? Kanna.html(html: parsedJson["d"]["results"].stringValue, encoding: .utf8)
for row in doc.css("td:nth-child(2)")
let link = row.at_css("a.result-title-tf")!
let location = row.at_css("a[target=_blank]")!
let schoolID = link["href"]!.components(separatedBy: "=")[1]
searchResults.append(["location": location.text!, "result": link.text!, "id":schoolID])
completionHandler(searchResults)
catch let error
print(error)
我想用 RxSwift 解决方案替换 cellForRowAt。
【问题讨论】:
【参考方案1】:根据您提供的代码,使用 Rx 将为您提供如下内容:
override func viewDidLoad()
super.viewDidLoad()
searchController.searchBar.rx.text.orEmpty
.filter text in text.count >= 3
.flatMapLatest text in searchRequest(search: text, searchType: "t:t")
.bind(to: self.tableView.rx.items(cellIdentifier: "cell", cellType: UITableViewCell.self)) row, element, cell in
if self.shouldShowSearchResults
cell.textLabel?.text = element["result"]!
cell.detailTextLabel?.text = element["location"]!
.disposed(by: disposeBag)
shouldShowSearchResults
在其中感觉格格不入。但除此之外它看起来不错。
以上假设您将 searchRequest 包装在一个返回可观察对象的函数中,如下所示:
func searchRequest(search: String, searchType: String) -> Observable<[[String: String]]>
return Observable.create observer in
searchRequest(search: search, searchType: searchType, completionHandler: result in
observer.onNext(result)
observer.onCompleted()
)
return Disposables.create()
上面是一个标准模式,它将使用回调的函数包装到返回Observable
的函数中。
【讨论】:
太棒了!用 Observable 替换闭包对我来说更好吗?我该怎么做呢? 我希望 RxAlamofire 已经编写了包装器,但我通常不使用 alamofire,所以我不确定。 您可能还喜欢查看这个示例程序。 github.com/dtartaglia/RxEarthquake我很乐意回答您对此的任何问题,只需发布问题,我会回答。 如果它返回Observable<[String: String]
> 怎么办?
表格视图需要一个对象数组。以上是关于使用 RxSwift 将 Alamofire 请求绑定到表视图的主要内容,如果未能解决你的问题,请参考以下文章
如何将 RxSwift 与 AlamoFire 和 SwiftyJSON 一起使用?
如何使用 RxSwift 和 Alamofire 使用分页?