使用 AlamoFire 获取数据以根据 UISearchBar 值填充 UITableView

Posted

技术标签:

【中文标题】使用 AlamoFire 获取数据以根据 UISearchBar 值填充 UITableView【英文标题】:Using AlamoFire to fetch data to populate UITableView based on UISearchBar value 【发布时间】:2017-05-23 12:02:23 【问题描述】:

与许多 JSON 请求不同,我打算根据输入到搜索栏中的内容发送 JSON 请求(使用 AlamoFire),而不是过滤预先确定的长 JSON,从而获取要解析的 JSON(使用 SwiftyJSON)填充 UITableView

我想做的是使用 searchTerm(在搜索栏中输入)通过 geonames API 请求的查询字段中的 searchTerm 向 Geonames 发送 AlamoFire 请求。即

http://api.geonames.org/searchJSON?formatted=true&q=(searchTerm)&maxRows=3&username=demo

我基本上不能做的是在填写搜索栏后发送请求,因此用该数据填充表。

下面是我当前的代码(它在视图加载时使用解析的 JSON 数据填充表格,并请求 "burpham"

import UIKit
import Alamofire
import SwiftyJSON

class SearchAddLocationViewController: UIViewController, UITableViewDataSource, UITableViewDelegate


@IBOutlet weak var tblJSON: UITableView!

@IBOutlet weak var searchbarValue: UISearchBar!

weak open var delegate: UISearchBarDelegate?

var arrRes = [[String:AnyObject]]() //Array of dictionary

override func viewDidLoad()

    super.viewDidLoad()


public func searchBarTextDidEndEditing(_ searchBar: UISearchBar) // called when text ends editing

    callAlamo(searchTerm: searchbarValue.text!)


func callAlamo(searchTerm: String)

    Alamofire.request("http://api.geonames.org/searchJSON?q=\(searchTerm)&maxRows=5&username=garethallenstringer").responseJSON  (responseData) -> Void in
        if((responseData.result.value) != nil) 
            let swiftyJsonVar = JSON(responseData.result.value!)

            if let resData = swiftyJsonVar["geonames"].arrayObject 
                self.arrRes = resData as! [[String:AnyObject]]
            
            if self.arrRes.count > 0 
                self.tblJSON.reloadData()
            
        
    


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    let cell : UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "addLocProtoCell")!
    var dict = arrRes[indexPath.row]
    cell.textLabel?.text = dict["name"] as? String
    cell.detailTextLabel?.text = dict["countryName"] as? String
    return cell


public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int

    return arrRes.count


override func didReceiveMemoryWarning()

    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.



【问题讨论】:

【参考方案1】:

您需要监听 UISearchBar 委托的 func searchBarTextDidEndEditing(_ searchBar: UISearchBar) 方法来填充您的 UITableView

class ViewController: UIViewController, UISearchBarDelegate 

    @IBOutlet private weak var searchBar: UISearchBar?

    override func viewDidLoad() 
        super.viewDidLoad()

        self.searchBar?.delegate = self
    

    //MARK: UISearchBarDelegate methods
    func searchBarSearchButtonClicked(_ searchBar: UISearchBar) 
       //You can do your request via Alamofire to populate tableView
    

更新 #1

import UIKit
import Alamofire
import SwiftyJSON

class SearchAddLocationViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UISearchBarDelegate


    @IBOutlet weak var tblJSON: UITableView!

    @IBOutlet weak var searchbarValue: UISearchBar!

    var arrRes = [[String:AnyObject]]() //Array of dictionary

    override func viewDidLoad()
    
        super.viewDidLoad()
        self.searchbarValue.delegate = self
    

    func searchBarSearchButtonClicked(_ searchBar: UISearchBar)  // called when text ends editing
    
        callAlamo(searchTerm: searchbarValue.text!)
    

    func callAlamo(searchTerm: String)
    
        Alamofire.request("http://api.geonames.org/searchJSON?q=\(searchTerm)&maxRows=5&username=garethallenstringer").responseJSON  (responseData) -> Void in
            if((responseData.result.value) != nil) 
                let swiftyJsonVar = JSON(responseData.result.value!)

                if let resData = swiftyJsonVar["geonames"].arrayObject 
                    self.arrRes = resData as! [[String:AnyObject]]
                
                if self.arrRes.count > 0 
                    self.tblJSON.reloadData()
                
            
        
    

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        let cell : UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "addLocProtoCell")!
        var dict = arrRes[indexPath.row]
        cell.textLabel?.text = dict["name"] as? String
        cell.detailTextLabel?.text = dict["countryName"] as? String
        return cell
    

    public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
    
        return arrRes.count
    

    override func didReceiveMemoryWarning()
    
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    


【讨论】:

所以我从这里看到searchBarTextDidEndEditing 将实际的UISearchBar 作为参数,这是否意味着用户在搜索栏中键入的任何字符串都是该类型的? func searchBarTextDidEndEditing(_ searchBar: UISearchBar) 将在用户完成搜索栏编辑后调用。 UISearchBar 有一个属性text,所以你可以像这样获取 searchBar 当前文本:func searchBarTextDidEndEditing(_ searchBar: UISearchBar) print(searchBar.text) 因此,为了添加 UISearchBarDelegate,必须简单地在顶部加上其他初始化程序/出口有 `weak open var delegate: UISearchBarDelegate?`?我相信我已经正确地添加了这些方法,但是当按下软件键盘上的搜索按钮时没有任何反应,尽管调用了一个名为 callAlamo 的函数,该函数从 searchBarDidEndEditing 函数中获取了一个字符串 (searchBar.text)。我将更新我的问题以反映代码的变化。 不,你不需要在你的代码中有weak open var delegate: UISearchBarDelegate?。只需在viewDidLoad() 中订阅UISearchBarDelegatesearchbarValue 即可:self.searchbarValue.delegate = self 这是否意味着我在初始化类时需要UISearchBarDelegate(以及UITableViewDataSourceUITableViewDelegate)?我以前作为 UITableView 的代表拥有它 - 这是不正确的吗?

以上是关于使用 AlamoFire 获取数据以根据 UISearchBar 值填充 UITableView的主要内容,如果未能解决你的问题,请参考以下文章

使用 Alamofire 获取数组键值

使用 alamofire + swift 获取动态加载的 html

alamofire 如何获取部分下载的数据?

使用 Swift 4 和 Alamofire 获取客户端证书以用于 Https 调用身份验证

Alamofire:有没有办法在失败的情况下获取响应数据?

在使用两个嵌套的 alamofire 请求滚动之前,TableView 不显示数据