UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

Multiple decode output (Choice)

Forums > Swift

Hi, does someone knows if I can output Type in more than one way with Encodable?

I mean say I have a Person struct

struct Person: Encodable {
  let first: String
  let last: String
  let age: Int
}

Is there a way to output just first and last or full detail based on some variable/flag?

I know I can create other structs or even enum with cases to work with, but I think there is a better way.

Thaks!

2      

@Bit-Worker, you can try something like this:

import Foundation

struct Person: Encodable {
    let first: String
    let last: String
    let age: Int

    var encodeAll: Bool = .random()
}

extension Person {
    enum AllCodingKeys: String, CodingKey {
        case first, last, age
    }

    enum JustNamesCodingKeys: String, CodingKey {
        case first, last
    }

    func encode(to encoder: Encoder) throws {
        if encodeAll {
            var container = encoder.container(keyedBy: AllCodingKeys.self)
            try container.encode(first, forKey: .first)
            try container.encode(last, forKey: .last)
            try container.encode(age, forKey: .age)
        } else {
            var container = encoder.container(keyedBy: JustNamesCodingKeys.self)
            try container.encode(first, forKey: .first)
            try container.encode(last, forKey: .last)
        }
    }
}

let mysteryKids: [Person] = [
    Person(first: "Charlotte", last: "Grote", age: 11),
    Person(first: "Shauna", last: "Wickle", age: 12),
    Person(first: "Mildred", last: "Haversham", age: 13),
    Person(first: "Linton", last: "Baxter", age: 12),
    Person(first: "Jack", last: "Finch", age: 12),
    Person(first: "Sonny", last: "Craven", age: 12),
]
print(mysteryKids)

do {
    let encoder = JSONEncoder()
    encoder.outputFormatting = .prettyPrinted
    let json = try encoder.encode(mysteryKids)
    print(String(data: json, encoding: .utf8)!)
} catch {
    print(error)
}

And some sample output:

[
  {
    "first" : "Charlotte",
    "last" : "Grote",
    "age" : 11
  },
  {
    "first" : "Shauna",
    "last" : "Wickle",
    "age" : 12
  },
  {
    "first" : "Mildred",
    "last" : "Haversham"
  },
  {
    "first" : "Linton",
    "last" : "Baxter"
  },
  {
    "first" : "Jack",
    "last" : "Finch",
    "age" : 12
  },
  {
    "first" : "Sonny",
    "last" : "Craven",
    "age" : 12
  }
]

Note that I added a property to Person to determine if all keys should be encoded or not, just for purposes of illustration. If your flag is something else, this should still be enough to get you on your way.

2      

Thanks, it's a way I tried to follow. My question is, in an async context like Vapor, changing the encodeAll boolean may cause problems, right? Say two clients are requesting two different encodings at same time, they could receive wrong encoded data? Thanks for your reply!

2      

Hacking with Swift is sponsored by Essential Developer

SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until April 28th.

Click to save your free spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.