Swiftpack.co -  abdalaliii/Unboxing as Swift Package
Swiftpack.co is a collection of thousands of indexed Swift packages. Search packages.
abdalaliii/Unboxing
An extension for KeyedDecodingContainer class to decode a collection of heterogeneous types.
.package(url: "https://github.com/abdalaliii/Unboxing.git", from: "1.1")

Unboxing

An extension for KeyedDecodingContainer class to decode a collection of heterogeneous types.

Usage

Start by creating an enum that has variants for the parsable type it must adhere to ClassFamily and define the type information discriminator.

enum DrinkFamily: String, ClassFamily {
    case drink = "drink"
    case beer = "beer"

    static var discriminator: Discriminator = .type
    
    typealias BaseType = Drink

    func getType() -> Drink.Type {
        switch self {
        case .beer:
            return Beer.self
        case .drink:
            return Drink.self
        }
    }
}

Later in your collection overload the init method to use our KeyedDecodingContainer extension.

class Bar: Decodable {
    let drinks: [Drink]

    private enum CodingKeys: String, CodingKey {
        case drinks
    }

    required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        drinks = try container.decodeHeterogeneousArray(OfFamily: DrinkFamily.self, forKey: .drinks)
    }
}

let barJson = """
{
    "drinks":
    [
        {"type": "drink", "description": "All natural"},
        {"type": "beer", "description": "best drunk on fridays after work", "alcohol_content": "5%"}
    ]
}
""".data(using: .utf8)!

let bar = try JSONDecoder().decode(Bar.self, from: barJson)

Otherwise follow the below example to decode an Hetegerenous json array object.

let drinksJson = """
[
    {"type": "drink", "description": "All natural"},
    {"type": "beer", "description": "best drunk on fridays after work", "alcohol_content": "5%"}
]
""".data(using: .utf8)!

let drinks = try JSONDecoder().decodeHeterogeneousArray(OfFamily: DrinkFamily.self, from: drinksJson)

Update

I've added the possibility to decode and flatten JSON with dynamic keys. Let's consider the following snippet:

{
  "1": {
    "name": "john"
  },
  "2": {
    "name": "smith"
  }
}

To extract the data from the above json, all you have to do is define your model and ask the JSONDecode to use DecodedArray new type.

struct Person: Decodable {
  let name: String
}

let _ = try JSONDecoder().decode(DecodedArray<Person>.self, from: barJson)

Installation

Swift Package Manager:

dependencies: [
    .package(url: "https://github.com/abdalaliii/Unboxing.git")
]

License

Unboxing is available under the MIT license. See the LICENSE file for more info.

GitHub

link
Stars: 0
Last commit: 4 weeks ago

Ad: Job Offers

iOS Software Engineer @ Perry Street Software
Perry Street Software is Jack’d and SCRUFF. We are two of the world’s largest gay, bi, trans and queer social dating apps on iOS and Android. Our brands reach more than 20 million members worldwide so members can connect, meet and express themselves on a platform that prioritizes privacy and security. We invest heavily into SwiftUI and using Swift Packages to modularize the codebase.

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