使用 Alamofire 和 Swift 3 反序列化复杂的 JSON
Posted
技术标签:
【中文标题】使用 Alamofire 和 Swift 3 反序列化复杂的 JSON【英文标题】:Deserialize complex JSON using Alamofire and Swift 3 【发布时间】:2017-05-26 09:39:47 【问题描述】:如何反序列化这个 JSON 并在 tableView 中显示标题 JSON:https://www.healthcare.gov/api/articles.json
到目前为止我所尝试的:
struct News
let title : String
init(dictionary: [String:String])
self.title = dictionary["mainTitle"] ?? ""
var newsData = [News]()
func downloadData()
Alamofire.request("https://www.healthcare.gov/api/articles.json").responseJSON response in
print(response.request as Any)
print(response.response as Any)
print(response.data as Any)
print(response.result.value)
self.newsData.removeAll()
if let json = response.result.value as? [[String:String]]
for news in json
self.newsData.append(News(dictionary: news))
self.tableView.reloadData()
override func viewDidLoad()
super.viewDidLoad()
downloadData()
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
override func numberOfSections(in tableView: UITableView) -> Int
return 1
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return newsData.count
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
let news = newsData[indexPath.row]
cell.textLabel?.text = news.title
return cell
服务器状态码是 200,所以我知道我的请求没问题。问题是我不知道如何创建合适的数据模型。
【问题讨论】:
【参考方案1】:JSON 令人困惑,因为在 articles
数组的末尾(应该只包含字典)有一个布尔值 false
,因此向下转换为 [[String:Any]]
失败。
你必须flatMap
数组忽略Bool
if let json = response.result.value as? [String:Any],
let articles = json["articles"] as? [Any]
for news in articles.flatMap($0 as? [String:Any])
self.newsData.append(News(dictionary: news))
self.tableView.reloadData()
并且键mainTitle
在JSON中不存在,在News
的init
方法中你必须写(字典是[String:Any]
而不是[string:String]
)
init(dictionary: [String:Any])
self.title = dictionary["title"] ?? ""
【讨论】:
你对parsedData是什么意思,它不存在但你把它分配给文章,编译器不让我运行它。 但是现在我的应用程序崩溃了,因为在这一行展开时有一个 nil self.newsData.append(News(dictionary: news as! [String : String] )) 字典是[String:Any]
。我更新了答案。并删除强制向下转换。【参考方案2】:
为了快速处理 JSON,我建议你使用 SwiftyJSON。 (https://github.com/SwiftyJSON/SwiftyJSON)
var myJson : JSON
func downloadData()
Alamofire.request("https://www.healthcare.gov/api/articles.json").responseJSON response in
print(response.request as Any)
print(response.response as Any)
print(response.data as Any)
print(response.result.value)
self.myJson = JSON(response.result.value)
self.tableView.reloadData()
现在您可以遍历 myJson
并调整 tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath)
以检索您的结果
【讨论】:
但是我怎样才能只提取标题呢?此外,您正在分配没有 JSON 信息的 response.result,它只有服务器标头。 JSON 可以在 response.result.value 下找到,但我不需要遍历整个数组,我只需要标题。【参考方案3】:用这个替换你的函数。
func downloadData()
Alamofire.request("https://www.healthcare.gov/api/articles.json").responseJSON response in
print(response.request as Any)
print(response.response as Any)
print(response.data as Any)
print(response.result.value)
self.newsData.removeAll()
if let json = response.result.value as? [String:AnyObject] //As outermost object in your JSON file is a dictionary
let article = json["articles"] as? [[String:AnyObject]] //Here you need to get inner object which is value for key "articles"
for news in article
self.newsData.append(News(dictionary: news))
self.tableView.reloadData()
您可以在http://www.jsoneditoronline.org/获得可读的 JSON
【讨论】:
【参考方案4】:尝试将您的响应映射到数据模型。然后你不需要反序列化你的 json。 https://github.com/insanoid/SwiftyJSONAccelerator 将帮助您创建数据模型。
【讨论】:
你说Try to map your response to a data model.
但 OP 已经在说“问题是我不知道如何创建合适的数据模型”。他们已经知道他们应该这样做。他们在问如何做到这一点。以上是关于使用 Alamofire 和 Swift 3 反序列化复杂的 JSON的主要内容,如果未能解决你的问题,请参考以下文章
Swift 3 的 ObjectMapper 和 Alamofire 问题 Alamofire 4 的 Alamofire 版本
带有 XML 响应和正文的 SOAP 请求 swift 3,Alamofire
JSON:使用 Alamofire 和 Swift 3 提取数据