I am getting the following JSON back from a network request:
{
"uvIndex": 5
}
I use the following type to decode the string-to-data result:
internal final class DataDecoder<T: Decodable> {
internal final class func decode(_ data: Data) -> T? {
return try? JSONDecoder().decode(T.self, from: data)
}
}
The following is the model that the data is to be transformed into:
internal struct CurrentWeatherReport: Codable {
// MARK: Properties
internal var uvIndex: Int?
// MARK: CodingKeys
private enum CodingKeys: String, CodingKey {
case uvIndex
}
// MARK: Initializers
internal init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
if let uvIndexInteger = try container.decodeIfPresent(Int.self, forKey: .uvIndex) {
uvIndex = uvIndexInteger
} else if let uvIndexString = try container.decodeIfPresent(String.self, forKey: .uvIndex) {
uvIndex = Int(uvIndexString)
}
}
}
The following are the tests used to verify the decoding:
internal final class CurrentWeatherReportTests: XCTestCase {
internal final func test_CurrentWeather_ReturnsExpected_UVIndex_FromIntegerValue() {
let string =
"""
{
"uvIndex": 5
}
"""
let data = DataUtility.data(from: string)
let currentWeatherReport = DataDecoder<CurrentWeatherReport>.decode(data)
XCTAssertEqual(currentWeatherReport?.uvIndex, 5)
}
internal final func test_CurrentWeather_ReturnsExpected_UVIndex_FromStringValue() {
let string =
"""
{
"uvIndex": "5"
}
"""
let data = DataUtility.data(from: string)
let currentWeatherReport = DataDecoder<CurrentWeatherReport>.decode(data)
XCTAssertEqual(currentWeatherReport?.uvIndex, 5)
}
}
The difference between the tests is the value of uvIndex in the JSON; one is a string and the other is an integer. I am expecting an integer, but I want to handle any cases in which the value may come back as a string rather than a number since that seems to be a common practice with a few APIs that I work with. However, my second test keeps failing with the following message: XCTAssertEqual failed: ("nil") is not equal to ("Optional(5)") -
Am I doing something incorrectly with regard to the Codable protocol that is causing this failure? If not, then what is causing my second test to fail with this seemingly-simple cast?
