我有来自服务器的以下数据
{
"success": true,
"terms": "https://currencylayer.com/terms",
"privacy": "https://currencylayer.com/privacy",
"timestamp": 1572365346,
"source": "USD",
"quotes": {
"USDBAM": 1.76456,
"USDTJS": 9.694558,
"USDYER": 250.349994,
"USDZAR": 14.592897,
.......
}
}
现在我创建了以下内容以使用 Codable
struct Resource<T: Decodable>: ItemList {
var quotes: Dictionary<String, Double>
var success: Bool
var terms: String
var privacy: String
var timestamp: Int
var source: String
}
protocol ItemList: Decodable {
associatedtype T:
var success: Bool {get}
var terms: String {get}
var privacy: String {get}
var timestamp: Int {get}
var source: String {get}
var quotes: T {get}
}
一切正常,但我想将“引号”作为单独的模型,所以我创建了另一个结构,如下所示
struct CurrencyModel: Decodable {
var quotes: Dictionary<String, Double>
}
修改后的'Resource'如下
struct Resource<T: Decodable>: ItemList {
var quotes: T
var success: Bool
var terms: String
var privacy: String
var timestamp: Int
var source: String
}
然后打电话
CurrencyLayerCommunicator().get(Resource<CurrencyModel>.self) { [weak self] item in
self?.handleResult(item)
}
但是这次我无法得到结果&得到解码错误
Failed to convert into JSON with error: The data couldn’t be read because it is missing.
请建议或指导如何解决此问题。
最佳答案
最大的错误是只打印error.localizedDescription
而不是 error
.
有了这个:
do {
let decoded = try JSONDecoder().decode(Resource<CurrencyModel>.self, from: jsonData)
print(decoded)
} catch {
print("Localized Description Error: \(error.localizedDescription)")
print("Full Error: \(error)")
}
你将拥有:
Localized Description Error: The data couldn’t be read because it is missing.
Full Error: keyNotFound(CodingKeys(stringValue: "quotes", intValue: nil), Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "quotes", intValue: nil)], debugDescription: "No value associated with key CodingKeys(stringValue: \"quotes\", intValue: nil) (\"quotes\").", underlyingError: nil))
更有用。
那么问题是你有两次 "quotes"
.
一个作为 ItemList
中的键, 另一个在 CurrencyModel
.
替换Resource<CurrencyModel>.self
与 Resource<[String: Double]>.self
它正在运行。
在 JSON 解码的情况下,我还建议当它不工作时为了调试打印反向版本(我在你的结构中用 Decodable
替换了 Codable
):
let currencyModel = CurrencyModel(quotes: ["Currency1": 0.1,
"Currency2": 0.2,
"Currency3": 0.3])
let ressources: Resource<CurrencyModel> = Resource(quotes: currencyModel,
success: true,
terms: "terms",
privacy: "privacy",
timestamp: 30,
source: "source")
do {
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let reversedJSONData = try encoder.encode(ressources)
if let reversedJSONString = String(data: reversedJSONData, encoding: .utf8) {
print(reversedJSONString)
}
} catch {
print("Error in reversing: \(error)")
}
这打印
{
"success" : true,
"quotes" : {
"quotes" : {
"Currency1" : 0.10000000000000001,
"Currency2" : 0.20000000000000001,
"Currency3" : 0.29999999999999999
}
},
"terms" : "terms",
"privacy" : "privacy",
"timestamp" : 30,
"source" : "source"
}
通过这种方式,您将看到使用当前代码应该看起来像 JSON 的内容。
请注意,如果有自定义初始化,您需要进行更改以反射(reflect)它。
关于ios - 如何快速传递关联类型中的 Codable 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58624387/