如何使用来自 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
的单元格样式。否则创建一个自定义单元,添加UILabel
s,子类UITableViewCell
,将自定义单元的类设置为该类,添加IBOutlet
s,将出口连接到标签,使用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 数组响应的某些部分