Skip to content

Instantly share code, notes, and snippets.

@DeveloperMaris
Last active February 22, 2021 15:36
Show Gist options
  • Save DeveloperMaris/e8357561c51f9df38d4e47474e80d88a to your computer and use it in GitHub Desktop.
Save DeveloperMaris/e8357561c51f9df38d4e47474e80d88a to your computer and use it in GitHub Desktop.
Decodable enum with associated values
//
// Original idea's author is Donny Wals.
// https://twitter.com/DonnyWals/status/1363840790322102275
//
// Example modified by Maris Lagzdins on 22/02/2021.
//
import Foundation
// Decodable enum with associated values.
enum Target: Decodable {
case settings
case webview(url: URL)
enum CodingKeys: CodingKey {
// Provide all possible keys from the JSON, which we need to access.
case target
case url
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let target = try container.decode(String.self, forKey: .target)
switch target {
case "settings":
self = .settings
case "webview":
// If the `target` is `webview`, then also decode the `url` key as an URL object.
let url = try container.decode(URL.self, forKey: .url)
self = .webview(url: url)
default:
// JSON contains unexpected `target` key value, throw error.
let context = DecodingError.Context(codingPath: decoder.codingPath,
debugDescription: "Unexpected target: \(target)")
throw DecodingError.dataCorrupted(context)
}
}
}
// ----- EXAMPLE -----
let data = """
[
{
"target": "settings"
},
{
"target": "webview",
"url": "https://www.apple.com"
}
]
""".data(using: .utf8)!
let targets: [Target] = try! JSONDecoder().decode([Target].self, from: data)
print(targets)
for target in targets {
switch target {
case .settings:
print("Navigate to settings")
case .webview(let url):
print("Navigate to webview and open the `\(url)`")
}
}
/* OUTPUT:
[Page_Contents.Target.settings, Page_Contents.Target.webview(url: https://www.google.com)]
Navigate to settings
Navigate to webview and open the `https://www.google.com`
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment