派生型プロパティを Decodable で扱う

macOS 開発

最近の Swift では Decodable に準拠したオブジェクトを簡単に JSON から変換できる。

struct Root: Decodable
{
    let texts: [String]
    let isFine: Bool
}

let root = try JSONDecoder().decode(Root.self, from: """
{
    "texts": ["hello", "again"],
    "isFine": true
}
""".data(using: .utf8)!)

root.texts //["hello", "again"]
root.isFine //true

上のようにあらかじめかっちりと定義した通りのデータが与えられるときは自動でやってくれて便利だけど、実際にはそうもいかなくて難しい。

例えば、次のようにバリエーションが複数ある場合:

protocol Parameter: Decodable
{
    var type: ParameterType { get }
}
struct BoolParameter: Parameter
{
    let type: ParameterType
    let defaultValue: Bool
}
struct NumberParameter: Parameter
{
    let type: ParameterType
    let defaultValue: CGFloat
    let minValue: CGFloat
    let maxValue: CGFloat
}
enum ParameterType: String, Decodable
{
    case bool
    case number
}

BoolParameter と NumberParameter は同列な存在でどちらも Parameter に準拠させている。JSON では独自の型情報を定義できないので Parameter.type を用意して区別することにする。

続きを読む

© 2005-2020 zumuya