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      

BUILD THE ULTIMATE PORTFOLIO APP Most Swift tutorials help you solve one specific problem, but in my Ultimate Portfolio App series I show you how to get all the best practices into a single app: architecture, testing, performance, accessibility, localization, project organization, and so much more, all while building a SwiftUI app that works on iOS, macOS and watchOS.

Get it on Hacking with Swift+

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.