【问题标题】:How do I populate a tableview with JSON data from Alamofire?如何使用来自 Alamofire 的 JSON 数据填充 tableview?
【发布时间】: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 语句并没有解决问题

标签: json swift uitableview alamofire


【解决方案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,因为它总是返回一个非可选的有效单元格。
猜你喜欢
  • 2023-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多