您正在混合使用两种不同的API。
要么使用 的 JSONSerialization 强> ,结果是一个字典,您可以通过密钥和索引订阅获取值。你必须向下转换每种类型并考虑嵌套 rate 值。
JSONSerialization
rate
guard let responseJSON = try? JSONSerialization.jsonObject(with: data) as? [String:Any], let info = responseJSON["info"] as? [String:Any], let rate = info["rate"] as? Double, let result = responseJSON["result"] as? Double else { return callback(false, nil) } let conversionResult = ConversionResult(exchangeRate: rate, exchangeResult: result) callback(true, conversionResult)
或者使用 的 JSONDecoder 强> 那么你必须创建结构,解码为 [String:Double] 只有在 的 所有 强> 根对象中的值是 Double 事实显然并非如此。
JSONDecoder
[String:Double]
Double
struct Root: Decodable { let info: Info let result: Double } struct Info: Decodable { let rate: Double } guard let responseJSON = try? JSONDecoder().decode(Root.self, from: data) else { return callback(false, nil) } let conversionResult = ConversionResult(exchangeRate: responseJSON.info.rate, exchangeResult: responseJSON.result) callback(true, conversionResult)
代码只是保留语法的一个示例。实际上,你强烈不鼓励使用 try? 解码JSON时。总是 catch 并处理错误
try?
catch
do { let responseJSON = try JSONDecoder().decode(Root.self, from: data) let conversionResult = ConversionResult(exchangeRate: responseJSON.info.rate, exchangeResult: responseJSON.result) callback(true, conversionResult) } catch { print(error) return callback(false, nil) }
使用真实的模型对象,如下所示:
struct Conversion: Codable { let success: Bool let query: Query let info: Info let historical, date: String let result: Double } struct Info: Codable { let timestamp: Int let rate: Double } struct Query: Codable { let from, to: String let amount: Int }
并使用以下内容解析您的响应 JSONDecoder :
do { let conversion = try JSONDecoder().decode(Conversion.self, from: data) let rate = conversion.info.rate let result = conversion.result } catch { print(error) }