Some APIs are not so accurate with the data types. So it can happen that, for example, all Int values in a json response are provided as text.
If you want to decode such a json with the JSONDecoder, you have to implement an extra decoding for each model, because the JSONDecoder does not offer the possibility to override the decoding of single types like Int.
With this framework, it is no longer necessary.
Open Package.swift
and add the package to your project's dependencies:
let package = Package(
// ...
dependencies: [
.package(url: "https://github.com/starke0o/custom-type-conversion-coder.git", from: "1.0.0")
]
)
let jsonDecoder = JSONDecoder()
let decoder = CustomTypeConversionDecoder(decoder: jsonDecoder)
Use valueDecodingStrategy(for:customDecoding:)
to define your own decoding strategy. The strategy is applied to all values with the same types.
// Decoding strategy for int values
decoder.valueDecodingStrategy(for: Int.self, customDecoding: { decoder in
let container = try decoder.singleValueContainer()
let stringValue = try container.decode(String.self)
guard let int = Int(stringValue) else {
throw DecodingError.typeMismatch(Int.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Expected to a String value containing a number"))
}
return int
})
customDecoding
is comparable to the decoding constructor init(from decoder: Decoder) throws
.
The CustomTypeConversionDecoder can be used like a normal JSONDecoder.
decoder.decode(Model.self, from: data)
decoder.valueDecodingStrategy(for: String.self, customDecoding: { decoder in
let container = try decoder.singleValueContainer()
return try container.decode(String.self)
.trimmingCharacters(in: .whitespacesAndNewlines)
})
decoder.valueDecodingStrategy(for: Bool.self, customDecoding: { decoder in
let container = try decoder.singleValueContainer()
let int = try container.decode(Int.self)
return int != 0
})
decoder.valueDecodingStrategy(for: Bool?.self, customDecoding: { decoder in
let container = try decoder.singleValueContainer()
let int = try container.decode(Int.self)
switch int {
case 1:
return true
case 0:
return false
default:
return nil
}
})
CustomTypeConversionCoder is released under an MIT license. See LICENCE for more information.
link |
Stars: 0 |
Last commit: 2 years ago |
Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics