Swiftpack.co - starke0o/custom-type-conversion-coder as Swift Package

Swiftpack.co is a collection of thousands of indexed Swift packages. Search packages.
See all packages published by starke0o.
starke0o/custom-type-conversion-coder 0.2.2
A way to provide custom conversion for decoders, such as the JSONDecoder.
⭐️ 0
🕓 2 weeks ago
.package(url: "https://github.com/starke0o/custom-type-conversion-coder.git", from: "0.2.2")

Swift Package Manager Build Status

Why?

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.

Installation

Swift Package

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")
    ]
)

How to

Wrap your decoder

let jsonDecoder = JSONDecoder()
let decoder = CustomTypeConversionDecoder(decoder: jsonDecoder)

Define custom decoding(s)

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.

Use the custom type conversion decoder

The CustomTypeConversionDecoder can be used like a normal JSONDecoder.

decoder.decode(Model.self, from: data)

Some examples

Trim string values

decoder.valueDecodingStrategy(for: String.self, customDecoding: { decoder in
    let container = try decoder.singleValueContainer()
    
    return try container.decode(String.self)
        .trimmingCharacters(in: .whitespacesAndNewlines)
})

Bool from 0 or 1

decoder.valueDecodingStrategy(for: Bool.self, customDecoding: { decoder in
    let container = try decoder.singleValueContainer()
    let int = try container.decode(Int.self)

    return int != 0
})

Bool of 0 or 1 and nil if none of them

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
    }
})

License

CustomTypeConversionCoder is released under an MIT license. See LICENCE for more information.

GitHub

link
Stars: 0
Last commit: 2 weeks ago
jonrohan Something's broken? Yell at me @ptrpavlik. Praise and feedback (and money) is also welcome.

Release Notes

0.2.1
12 weeks ago
  • Added support for optional value decoding

Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics