Home > Software design >  I want to use enum value as type in Swift
I want to use enum value as type in Swift

Time:02-18

I defined this structure.

import Foundation
import SwiftUI

struct Hoge: Hashable, Codable {
    var id: Int
    var type: Type
}

enum Type: Codable {
    case one
    case two
}

And I created json.

[
    {
        "id": 1,
        "type": "one",
    },
    ...
]

And this is decode and load json file.

import Foundation
var hogeList: [Hoge] = load("hoge.json")
func load<T: Decodable>(_ filename: String) -> T {
    let data: Data
    guard let file = Bundle.main.url(forResource: filename, withExtension: nil) else {
        fatalError("Couldnt find \(filename) in main bundle.")
    }
    do {
        data = try Data(contentsOf: file)
    } catch {
        fatalError("Couldnt load \(filename) from main bundle:\n\(error)")
    }
    do {
        let decoder = JSONDecoder()
        return try decoder.decode(T.self, from: data)
    } catch {
        fatalError("Couldnt parse \(filename) as \(T.self):\n\(error)")
    }
}

Crach logs shows this logs.

Fatal error: Couldnt parse hoge.json as Array: typeMismatch(Swift.Dictionary<Swift.String, Any>, Swift.DecodingError.Context(codingPath: [_JSONKey(stringValue: "Index 0", intValue: 0), CodingKeys(stringValue: "type", intValue: nil)], debugDescription: "Expected to decode Dictionary<String, Any> but found a string/data instead.", underlyingError: nil))

CodePudding user response:

You have two issues in your code:

a) there is an extra comma in your JSON which makes it invalid. Remove the comma after "one"

[
    {
        "id": 1,
        "type": "one"
    }

]

b) You need to declare your enumeration type as String:

enum Type: String, Codable {
    case one, two
}

Note: I would also rename the enumeration from Type to Kind. You would need to change your json as well or provide a custom CodingKeys to your struct

  • Related