问题
Looking for some input as to how you would handle the scenario I recently ran into.
I have been using Swift 4s Codable with success but today noticed a crash that I didn't expect. The API that I am working with, says it returns a boolean
for the key manage_stock
.
My stubbed struct looks like:
struct Product: Codable {
var manage_stock: Bool?
}
That works fine, the problem is that the API sometimes returns a string
instead of a boolean
.
Because of this, my decode fails with:
Expected to decode Bool but found a string/data instead.
The string only ever equals "parent"
and I want it to equate to false
.
I am also fine with changing my struct to var manage_stock: String?
if that makes things easier to bring the JSON data in from the API. But of course, if I change that, my error just changes to:
Expected to decode String but found a number instead.
Is there a simple way to handle this mutation or will I need to lose all the automation that Codable
brings to the table and implement my own init(decoder: Decoder)
.
Cheers
回答1:
Since you can't always be in control of the APIs you're working with, here's one simple way to solve this with Codable
directly, by overriding init(from:)
:
struct Product : Decodable {
// Properties in Swift are camelCased. You can provide the key separately from the property.
var manageStock: Bool?
private enum CodingKeys : String, CodingKey {
case manageStock = "manage_stock"
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
do {
self.manageStock = try container.decodeIfPresent(Bool.self, forKey: .manageStock)
} catch DecodingError.typeMismatch {
// There was something for the "manage_stock" key, but it wasn't a boolean value. Try a string.
if let string = try container.decodeIfPresent(String.self, forKey: .manageStock) {
// Can check for "parent" specifically if you want.
self.manageStock = false
}
}
}
}
See Encoding and Decoding Custom Types for more info on this.
来源:https://stackoverflow.com/questions/48621515/swift-4-codable-bool-or-string-values