enum PostType: Decodable {
init(from decoder: Decoder) throws {
// What do i put here?
}
case Image
enum CodingKeys: String, CodingKey {
You can do what you want, but it is a bit involved :(
import Foundation
enum PostType: Codable {
case count(number: Int)
case comment(text: String)
init(from decoder: Decoder) throws {
self = try PostTypeCodableForm(from: decoder).enumForm()
}
func encode(to encoder: Encoder) throws {
try PostTypeCodableForm(self).encode(to: encoder)
}
}
struct PostTypeCodableForm: Codable {
// All fields must be optional!
var countNumber: Int?
var commentText: String?
init(_ enumForm: PostType) {
switch enumForm {
case .count(let number):
countNumber = number
case .comment(let text):
commentText = text
}
}
func enumForm() throws -> PostType {
if let number = countNumber {
guard commentText == nil else {
throw DecodeError.moreThanOneEnumCase
}
return .count(number: number)
}
if let text = commentText {
guard countNumber == nil else {
throw DecodeError.moreThanOneEnumCase
}
return .comment(text: text)
}
throw DecodeError.noRecognizedContent
}
enum DecodeError: Error {
case noRecognizedContent
case moreThanOneEnumCase
}
}
let test = PostType.count(number: 3)
let data = try JSONEncoder().encode(test)
let string = String(data: data, encoding: .utf8)!
print(string) // {"countNumber":3}
let result = try JSONDecoder().decode(PostType.self, from: data)
print(result) // count(3)