请求帮助alamofire(两天我找不到并理解错误);在任务上我需要通过api获取JSON数据并自动“展开”它们
var articles = [Articles]()
这些值(JSON)来了并打印,但由于错误的方法/结构,我无法自动展开它们。
let api_url = "https://newsapi.org/v2/everything?q=bitcoin&from=2019-03-13&sortBy=publishedAt&apiKey=xxx"
let formatter = "https://jsonformatter.curiousconcept.com/"
和
struct Articles: Decodable {
var author: String?
var content: String?
var description: String?
var publishedAt: String?
var title: String?
var url: String?
var urlToImage: String?
init(dict: [String: Any]) {
let author = dict["author"] as? String ?? ""
// some let's...
let urlToImage = dict["urlToImage"] as? String ?? ""
self.author = author
// some self's...
self.publishedAt = publishedAt
}
static func getArray(from arrayOfItems: Any) -> [Articles]? {
guard let arrayOfItems = arrayOfItems as? Array<[String: Any]>
else { print("ERROR at ArticleModel -> Articles"); return nil }
return arrayOfItems.compactMap { Articles(dict: $0) }
}
}
//Download Data
func fetchDataWithAlamofire() {
guard let url = URL(string: api_url) else { return }
request(url).validate().responseJSON { (dataResponse) in
switch dataResponse.result {
case .success(let value):
print(value)
if let response = Articles.getArray(from: value) {
self.articles = response
}
DispatchQueue.main.async {
self.tableView.reloadData()
}
case .failure(let error):
print(error)
}
}
}
我获得的JSON数据必须自动(通过一种方法)在数组中展开并显示在模拟器单元格中(我已经制作了单元格,这是Array / Dict / Struct中的一个问题)
首先,为什么你的结构符合Decodable
,尽管你根本不使用JSONDecoder
?
你犯了一个常见错误,你忽略了根对象。你需要两个结构,请以单数形式命名Article
。
struct Root : Decodable {
let status : String
let totalResults : Int?
let message : String? // message is used in case of an error
let articles : [Article]?
}
struct Article : Decodable {
let author : String?
let content : String?
let description : String
let publishedAt : Date
let title : String
let url : URL
let urlToImage : URL?
}
不需要Article
中的初始化程序和静态函数。
在fetchDataWithAlamofire()
使用responseData
而不是responseJSON
并使用JSONDecoder
解码JSON。
url
和urlToImage
可以直接解码为URL
和publishedAt
可以解码为Date
func fetchDataWithAlamofire() {
guard let url = URL(string: api_url) else { return }
request(url).validate().responseData { dataResponse in
switch dataResponse.result {
case .success(let data):
do {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
let result = try decoder.decode(Root.self, from: data)
self.articles = result.articles
DispatchQueue.main.async {
self.tableView.reloadData()
}
} catch {
print(error)
}
case .failure(let error):
print(error)
}
}
}