如何使用来自 Alamofire 的 JSON 数据填充 tableview?

Posted

技术标签:

【中文标题】如何使用来自 Alamofire 的 JSON 数据填充 tableview?【英文标题】:How do I populate a tableview with JSON data from Alamofire? 【发布时间】:2017-10-26 01:24:03 【问题描述】:

在我陈述我的问题之前,我想让大家知道我是 Swift 编码环境的新手,所以请原谅我缺乏知识。目前,我无法根据从 JSON URL 返回的数据使用 Alamofire 填充表格视图的单元格。当我在模拟器中运行应用程序时,数据会显示在控制台中,但应用程序会因 SIGABRT 错误而崩溃。作为参考,我没有使用带有 tableview 元素的 viewcontroller,而是使用 tableviewcontroller。到目前为止,这是我的代码:

import UIKit
import Alamofire

class TableViewController: UITableViewController 
    var responseArray: NSArray = []

    override func viewDidLoad() 
        super.viewDidLoad()
        Alamofire.request("https://rss.itunes.apple.com/api/v1/us/apple-music/top-songs/all/10/explicit.json").responseJSON  response in
            if let json = response.result.value 
                print(json)
                self.responseArray = json as! NSArray
            
        
    

    override func numberOfSections(in tableView: UITableView) -> Int 
        return 1
    

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

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        let cell = tableView.dequeueReusableCell(withIdentifier: "top10", for: indexPath)

        // Configure the cell...
        let whichSong = responseArray[(indexPath as NSIndexPath).row]
        let artistName = (whichSong as AnyObject)["artistName"] as? String
        cell.textLabel?.text = artistName

        return cell
    

【问题讨论】:

究竟是哪一行导致了错误?控制台中的完整错误消息是什么? 你使用的是 Storyboard 还是 XIB ?? 我正在使用 Xcode 中提供的故事板。至于错误,似乎是来自self.responseArray = json as! NSArray。另外,json请求后是否需要重新加载数据? 你没有重新加载你的表 很遗憾,添加 reload 语句并没有解决问题 【参考方案1】:

发生崩溃是因为 JSON 的根对象是 字典(由 表示)而不是数组。

首先声明一个 JSON 字典和数据源数组的类型别名为原生类型,一个 JSON 字典数组:

typealias JSONDictionary = [String:Any]
var responseArray = [JSONDictionary]()

然后解析 JSON 并重新加载表格视图,您可能需要键 results 的数组:

Alamofire.request("https://rss.itunes.apple.com/api/v1/us/apple-music/top-songs/all/10/explicit.json").responseJSON  response in
      if let json = response.result.value as? JSONDictionary,
         let feed = json["feed"] as? JSONDictionary,
         let results = feed["results"] as? [JSONDictionary] 
             print(results)
             self.responseArray = results
             self.tableView.reloadData()
         

然后显示cellForRow中的数据

let song = responseArray[indexPath.row]
cell.textLabel?.text = song["artistName"] as? String

【讨论】:

虽然这消除了错误,但似乎没有打印任何内容,并且 tableview 中没有显示任何数据 我的错,键 feed 有一个根对象。我更新了答案。 效果很好,非常感谢。答案已更新! 还有一个问题。如何使用它在一个单元格中加载多个字典元素? 如果您只想显示 一个 附加值,请使用提供detailTextLabel 的单元格样式。否则创建一个自定义单元,添加UILabels,子类UITableViewCell,将自定义单元的类设置为该类,添加IBOutlets,将出口连接到标签,使用cellForRow 中的自定义单元格并将其他字典值分配给标签。【参考方案2】:

好的,所以先改变

let cell = tableView.dequeueReusableCell(withIdentifier: "top10", for: indexPath)

let cell = tableView.dequeueReusableCell(withIdentifier: "top10") 

但是,cell 将变为 cell?,您必须返回 cell!

在您的 Alamofire 响应中,

 if let json = response.result.value 
     print(json)
     self.responseArray = json as! NSArray
     self.reloadData()
     //If above line doesn't work, try tableView.reloadData()
 

为什么?

Alamofire 请求是“异步的”,这意味着它会在您的应用执行其他操作时执行代码。因此,您很可能在加载表格后设置该数组,因此reloadData()

【讨论】:

不建议这样做。 dequeueReusableCell(withIdentifier:for:) 是推荐的 API,因为它总是返回一个非可选的有效单元格。与问题无关。【参考方案3】:

替换下面的行

let cell = tableView.dequeueReusableCell(withIdentifier: "top10", for: indexPath)

let cell = tableView.dequeueReusableCell(withIdentifier: "top10")

【讨论】:

通过此更改,cell 是可选的,可能是 nil。需要添加额外的代码来检查并根据需要创建单元格。在 OP 发布有关错误的更多详细信息之前,这个答案还为时过早。 不建议这样做。 dequeueReusableCell(withIdentifier:for:) 是推荐的 API,因为它总是返回一个非可选的有效单元格。

以上是关于如何使用来自 Alamofire 的 JSON 数据填充 tableview?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Alamofire 和 SwiftyJSON 正确创建一个类来保存来自 JSON 的数据

如何在 Swift 中解析来自 Alamofire API 的 JSON 响应?

如何显示来自 Alamofire 请求的 JSON 数组响应的某些部分

Swift 4 - 如何在 UIAlert 中显示来自 JSON Alamofire 的错误响应

遍历来自 Alamofire 的 JSON 响应

如何使用 Alamofire,Swift 4 为 UICollectionView 获取 JSON 数据