【发布时间】:2024-01-16 05:51:02
【问题描述】:
我正在尝试让搜索结果显示在 tableView 上。我相信我已经正确解析了 JSON,唯一的问题是结果不会显示在我的 tableView 上。
代码如下:
var searchText : String! {
didSet {
getSearchResults(searchText)
}
}
var itemsArray = [[String:AnyObject]]()
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.delegate = self
self.tableView.dataSource = self
self.tableView.reloadData()
}
// MARK: - Get data
func getSearchResults(text: String) {
if let excapedText = text.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet()) {
Alamofire.request(.GET, "https://api.duckduckgo.com/?q=\(excapedText)&format=json")
.responseJSON { response in
guard response.result.error == nil else {
// got an error in getting the data, need to handle it
print("error \(response.result.error!)")
return
}
let items = JSON(response.result.value!)
if let relatedTopics = items["RelatedTopics"].arrayObject {
self.itemsArray = relatedTopics as! [[String:AnyObject]]
}
if self.itemsArray.count > 0 {
self.tableView.reloadData()
}
}
}
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 6 // itemsArray.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("SearchResultCell", forIndexPath: indexPath) as! SearchResultCell
if itemsArray.count > 0 {
var dict = itemsArray[indexPath.row]
cell.resultLabel?.text = dict["Text"] as? String
} else {
print("Results not loaded yet")
}
return cell
}
如果我有一个静态 API 请求,我认为这段代码会起作用,因为我可以在 viewDidLoad 中获取并避免大量 .isEmpty 检查。
当我运行程序时,我得到了 6 个 Results not loaded yet(来自我的 print in cellForRowAtIndexPath)。
当完成处理程序被称为response in 时,它会下降到self.items.count > 3(它通过)然后点击self.tableView.reloadData(),它什么都不做(我通过在其上放置断点进行检查)。
我的代码有什么问题?
编辑
if self.itemsArray.count > 0 {
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.tableView.reloadData()
})
}
试过了,但即使在调用 alamofire 处理程序之前重新加载了 6 次,tableView 仍然没有重新加载...
这是奇怪的事情,很明显在hander 被调用之前我的itemsArray.count 将是0,所以这就是我得到Results not loaded yet 的原因。我弄清楚了为什么它会重复 6 次;我将其设置为numberOfRowsInSection...所以@Rob,我无法检查dict["Text"] 或cell.resultLabel?.text,因为它们永远不会被调用。 “文本”是正确的,这里是 JSON 的链接:http://api.duckduckgo.com/?q=DuckDuckGo&format=json&pretty=1
另外,我确实将标签链接到自定义单元格类SearchResultCell
最后,我得到了可见的结果。
【问题讨论】:
-
我会怀疑线程问题,但如果我没记错的话,所有
Alamofire.request完成闭包无论如何都会在主线程上调用,因此除非您以其他方式配置 Alamofire,否则这应该不是问题。 (所有 UI 更改必须在主线程上执行) -
是的,这些都发生在主线程上,因此不太可能出现线程问题。更有可能的是(a)单元子类的出口没有正确定义; (b) 字典不包含由
Text键入的值;或 (c) 单元格中的约束使得标签内容的更改不可见。在 Wesley 分享更多调试细节之前,无法进行诊断。 -
您说“当我运行程序时,我得到 6 个结果‘尚未加载’(来自我在
cellForRowAtIndexPath中的打印结果)。”嗯,你应该得到那些。该表被加载两次,一次是在第一次加载时,一次是在您执行查询时。第一次你会得到六个“尚未加载”。第二次应该是填充单元格。
标签: ios json swift uitableview alamofire