Ios 解码JSON错误“;但却找到了一本字典;
我正在使用api制作今天iOS应用程序的历史记录 以下是我的数据结构:Ios 解码JSON错误“;但却找到了一本字典;,ios,json,swift,api,Ios,Json,Swift,Api,我正在使用api制作今天iOS应用程序的历史记录 以下是我的数据结构: struct HistoryAPIResponse: Codable { let data: [Events] } struct Events: Codable { let year: String let text: String let html: String } 这就是我如何从中获取数据: 导入UIKit final class HistoryAPICaller {
struct HistoryAPIResponse: Codable {
let data: [Events]
}
struct Events: Codable {
let year: String
let text: String
let html: String
}
这就是我如何从中获取数据:
导入UIKit
final class HistoryAPICaller {
static let shared = HistoryAPICaller()
struct Constants {
static let topHeadLinesURL = URL(string:
"http://history.muffinlabs.com/date/4/19"
)
static let searchUrlString =
"http://history.muffinlabs.com/date/4/19"
}
private init() {}
public func getTopStories(completion: @escaping (Result<[Events], Error>) -> Void) {
guard let html = Constants.topHeadLinesURL else {
return
}
let task = URLSession.shared.dataTask(with: html) { data, _, error in
if let error = error {
completion(.failure(error))
}
else if let data = data {
do {
_ = try JSONDecoder().decode(HistoryAPIResponse.self, from: data)
}
catch {
completion(.failure(error))
}
}
}
task.resume()
}
public func search(with query: String, completion: @escaping (Result<[Events], Error>) -> Void) {
guard !query.trimmingCharacters(in: .whitespaces).isEmpty else {
return
}
let urltring = Constants.searchUrlString + query
guard let html = URL(string:urltring) else {
return
}
let task = URLSession.shared.dataTask(with: html) { data, _, error in
if let error = error {
completion ( .failure(error))
}
else if let data = data {
do {
_ = try JSONDecoder().decode(HistoryAPIResponse.self, from: data)
}
catch {
completion (.failure(error))
}
}
}
task.resume()
}
}
final class HistoryAPICaller{
静态let shared=HistoryAPICaller()
结构常数{
静态let topHeadLinesURL=URL(字符串:
"http://history.muffinlabs.com/date/4/19"
)
静态let searchUrlString=
"http://history.muffinlabs.com/date/4/19"
}
私有init(){}
public func getTopStories(完成:@escaping(Result)->Void){
guard let html=Constants.topHeadLinesURL else{
回来
}
让task=URLSession.shared.dataTask(with:html){data,\中出现错误
如果let error=error{
完成(.failure(error))
}
如果let data=data,则为else{
做{
_=尝试JSONDecoder().decode(HistoryAPIResponse.self,from:data)
}
抓住{
完成(.failure(error))
}
}
}
task.resume()
}
公共函数搜索(带查询:字符串,完成:@escaping(Result)->Void){
guard!query.trimmingCharacters(在:。空格中)。isEmpty else{
回来
}
设urltring=Constants.searchUrlString+query
guard let html=URL(字符串:urltring)else{
回来
}
让task=URLSession.shared.dataTask(with:html){data,\中出现错误
如果let error=error{
完成(.failure(error))
}
如果let data=data,则为else{
做{
_=尝试JSONDecoder().decode(HistoryAPIResponse.self,from:data)
}
抓住{
完成(.failure(error))
}
}
}
task.resume()
}
}
其中一条错误信息显示:
类型不匹配(Swift.Array,Swift.DecodingError.Context(codingPath:[CodingKeys(stringValue:“data”,intValue:nil)],debugDescription:“应解码数组,但找到了字典。”,underyingerror:nil))
我有点理解问题的本质,数据就是一本字典。但我不知道如何解决它,因为这是API的结构,所有东西都存储在[数据]中
你知道如何解决这个问题吗?提前感谢您的帮助。您需要帮助
let res = try JSONDecoder().decode(Root.self, from: data)
让数据:[Events]
出错。在访问Events
之前,您会看到JSON中有一个键Events
,它缺少一个步骤。struct HistoryAPIResponse:Codable{let data:HistoryAPIResponse}struct HistoryAPIResponse:Codable{let Events:[Events]}
应该可以做到这一点。但最好通过设置自定义编码键或键策略来命名let events
而不是letevents
。如果不需要中间结构,也可以使用自定义的init(解码器:)
。谢谢您的帮助。数据结果正常,但现在我在将获取的数据返回tableView时遇到了问题。我现在使用do{let result=try JSONDecoder().decode(HistoryAPIResponse.self,from:data)print(“Articles:(result.data.count)”)completion(.success(result.data))}catch{completion(.failure(error))}它表示“HistoryDataAPIResponse”类型的值没有成员“count”,无法将“HistoryDataAPIResponse”类型的值转换为预期的参数类型“[Events]现在是result.data.Events.count
谢谢你的回答,这个也可以!
struct Root: Codable {
let data: HistoryAPIResponse
}
struct HistoryAPIResponse: Codable {
let events: [Events]
private enum CodingKeys : String, CodingKey {
case events = "Events"
}
}
struct Events: Codable {
let year,text,html: String
}