我从API获取数据,该数据每天都会从String
到Double
不定期地多次更改格式。
是否可以对struct
执行某些操作以防止在提取时返回nil并使用正确的类型自动使用?
struct BitcoinGBP : Decodable {
let price : Double
let percentChange24h : Double
private enum CodingKeys : String, CodingKey {
case price = "PRICE"
case percentChange24h = "CHANGEPCT24HOUR"
}
}
只需使用Double?
吗?
答案 0 :(得分:0)
编写自定义初始化程序以处理这两种情况
struct BitcoinGBP : Decodable {
let price : Double
let percentChange24h : Double
private enum CodingKeys : String, CodingKey {
case price = "PRICE"
case percentChange24h = "CHANGEPCT24HOUR"
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
percentChange24h = try container.decode(Double.self, forKey: .percentChange24h)
do {
price = try container.decode(Double.self, forKey: .price)
} catch DecodingError.typeMismatch(_, _) {
let stringValue = try container.decode(String.self, forKey: .price)
price = Double(stringValue)!
}
}
}
答案 1 :(得分:0)
根据我的经验,您需要设计您的结构,模型以符合您期望在应用程序中使用的内容,而不是API将为您提供的内容。您需要为API做好准备,以便为您提供不正确的数据类型或缺少奇怪的数据。
如果API变化太大,则用户需要更新,但通常不会这样做。端点必须具有版本,并且在产生巨大差异时需要更改版本。如果不是这种情况,它是有缺陷的API(这些事情仍然会发生),在这种情况下你应该使用自己的服务器,代理连接到所需的服务器并修改他们自己的API。您对其进行了一些测试,以检测其API是否已更改并尽快修改自己的API,以便所有应用程序仍然可以连接到它。但这超出了这个问题的范围。
如果您的结构必须在24小时内有价格和百分比变化,而两者都是双倍,那么只需要来自API的字符串或任何内容。我喜欢避免任何自动执行此操作的工具,因此我只使用便利构造函数和我自己的一组工具来生成类似的东西:
class BitcoinGBP {
var price: Double = 0.0
var priceChange24h: Double = 0.0
convenience init(price: Double, priceChange24h: Double) {
self.init()
self.price = price
self.priceChange24h = priceChange24h
}
/// Construuctor designed to accept JSON formated dictionary
///
/// - Parameter descriptor: A JSON descriptor
convenience init(descriptor: [String: Any]) {
self.init()
self.price = double(value: descriptor["PRICE"]) ?? 0.0
self.priceChange24h = double(value: descriptor["CHANGEPCT24HOUR"]) ?? 0.0
}
/// A conveninece method to extract a double value
///
/// - Parameter value: A value to be converted
/// - Returns: Double value if possible
func double(value: Any?) -> Double? {
if let value = value as? String {
return Double(value)
} else if let value = value as? Double {
return value
} else if let value = value as? Float {
return Double(value)
} else if let value = value as? Int {
return Double(value)
} else if let value = value as? Bool {
return value ? 1.0 : 0.0
} else {
return nil
}
}
}
现在剩下的就是取决于你需要什么功能。