我从返回数组的API中获取数据,但需要用具有“子级别”的API替换它:
RAW: ETH: USD: TYPE: "5" MARKET: "CCCAGG" FROMSYMBOL: "ETH" TOSYMBOL: "USD" PRICE: 680.89 CHANGEPCT24HOUR : -9.313816893529749
这是我的结构:
struct Ethereum: Codable { let percentChange24h: String let priceUSD: String private enum CodingKeys: String,CodingKey { case priceUSD = "PRICE",percentChange24h = "CHANGEPCT24HOUR" } }
并实施:
func fetchEthereumInfo(completion: @escaping (Ethereum?,Error?) -> Void) { let url = URL(string: "https://min-api.cryptocompare.com/data/pricemultifull?fsyms=ETH&tsyms=USD")! let task = URLSession.shared.dataTask(with: url) { (data,response,error) in guard let data = data else { return } do { if let ethereumUSD = try JSONDecoder().decode([Ethereum].self,from: data).first { print(ethereumUSD) completion(ethereumUSD,nil) } } catch { print(error) } } task.resume() }
控制台打印typeMismatch(Swift.Array< Any>,Swift.DecodingError.Context(codingPath:[],debugDescription:“预期解码数组< Any>但是找到了一个字典.”,underlyingError:nil))
首先,JSON不包含任何数组.阅读JSON非常容易.只有2个(两个!)集合类型,array []和字典{}.如您所见,JSON字符串中根本没有方括号.
任何(子)字典{}必须被解码为它自己的类型,所以它应该是
struct Root : Decodable { private enum CodingKeys : String,CodingKey { case raw = "RAW" } let raw : RAW } struct RAW : Decodable { private enum CodingKeys : String,CodingKey { case eth = "ETH" } let eth : ETH } struct ETH : Decodable { private enum CodingKeys : String,CodingKey { case usd = "USD" } let usd : USD } struct USD : Decodable { private enum CodingKeys : String,CodingKey { case type = "TYPE" case market = "MARKET" case price = "PRICE" case percentChange24h = "CHANGEPCT24HOUR" } let type : String let market : String let price : Double let percentChange24h : Double }
要解码JSON并打印percentChange24h,您必须编写
let result = try JSONDecoder().decode(Root.self,from: data) print("percentChange24h",result.raw.eth.usd.percentChange24h)