1

I'd like to use the same struct to fetch from different APIs, for that I need to be able to change the enum string depending on what I need to fetch as follows:

static var menuSelection: String = ""

if ... {
    menuSelection = "1"
} else if ... {
    menuSelection = "2"
} else {
    menuSelection = "3"
}

struct Order : Decodable {
    private enum CodingKeys : String, CodingKey { case raw = "RAW" }
    let raw : MenuRAW
}

struct MenuRAW : Decodable {
    private enum CodingKeys : String, CodingKey { case menu = "\(menuSelection)" } // <---- raw value for enum case must be a literal
    let menu : MenuReference
}

struct MenuReference : Decodable {
    private enum CodingKeys : String, CodingKey {
        case usd = "USD"
        case eur = "EUR"
        case gbp = "GBP"
        case cny = "CNY"
        case rub = "RUB"
    }
    let usd : MenuUSD?
    let eur : MenuEUR?
    let gbp : MenuGBP?
    let cny : MenuCNY?
    let rub : MenuRUB?
}

But I get a raw value for enum case must be a literal as "\(menuSelection)"doesn't seem to be a literal. What is my solution here?

Wizzardzz
  • 781
  • 1
  • 9
  • 32

1 Answers1

2

You can do it in a different way, create enum with parameter

enum CodingKeys {
    case menu(menuSelection: String)

    var stringValue: String? {
        switch self {
        case let .menu(menuSelection):
            return menuSelection
        default:
            return nil
        }
    }
}

and now you can use stringValue instead of rawValue like this

CodingKeys.menu(menuSelection: "You parameter").stringValue

Taras Chernyshenko
  • 2,729
  • 14
  • 27
  • Thanks a lot! This seems like the solution. I updated my code in the question with the full `struct`. Could you tell me if your solution is still viable this way? – Wizzardzz Feb 26 '18 at 13:45
  • 2
    `CodingKeys` related to `Codable` doesn't support associated values. You can declare them but they can't be used for decoding. – vadian Feb 26 '18 at 13:47
  • @vadian Could you give me a code example of what you would do in my case? I'm really curious to see – Wizzardzz Feb 26 '18 at 13:53
  • @Martin33000 Honestly I don't understand what you are going to accomplish. What is the selection `"1"`, `"2"`, `"3"` representing? – vadian Feb 26 '18 at 13:57
  • @vadian "1", "2" and "3" would be dictionary keys (I guess?) in the APIs I am fetching from (ex: https://min-api.cryptocompare.com/data/pricemultifull?fsyms=BTC&tsyms=USD, "1" would be "BTC" here, "2" would be "ETH" in another API..). So I could fetch data from different API addresses with the same struct by changing the url when needed. – Wizzardzz Feb 26 '18 at 14:06
  • @Martin33000 In your case I recommend to decode a dictionary `[String:Currency]` where `Currency` is the object containing the keys `TYPE`, `MARKET`, `FROMSYMBOL` etc. Then you can switch on the key which represents `USD` etc. – vadian Feb 26 '18 at 14:11
  • Oh I get it! I could just do what I did for the currency `struct MenuReference` but for `MenuRAW` and list different cases for different menus. I would then have to update the url address in the function fetching from the API right? This worked for the currency so should work for the menu too. How did I not think about it! – Wizzardzz Feb 26 '18 at 14:16
  • Very convenient solution! – liudasbar Jan 31 '22 at 16:51