LoginSignup
3
4

More than 5 years have passed since last update.

float3をCodableに対応させる(Swift4)

Last updated at Posted at 2018-01-29

はじめに

Swift4からCodableを使ってJsonを簡単に扱えるようになりました。
ゲームのマルチプレイを実装する上で、float3をJsonで送る必要がありました。
そこで、float3をCodableに対応させました。

Codableに対応させるということ

Codableに対応させるためには、Encodableプロトコルと、Decodableプロトコルに対応させる必要があります。

実装方法

Encodable, Decodableプロトコルに対応させるためにContainerに入れるのですが、KeyedContainer, SingleValueContainer, UnkeyedContainerの3つがあります。

Jsonをエンコード、デコードするコード

JSONEncoderとJSONDecoderを使ってCodableに対応したJsonに変換します。

        struct Message: Codable {
            var result: Bool
            var position: float3
        }
        do {
            let msg = Message(result: true, position: float3(1.2, 3.4, -5.1))

            let data = try JSONEncoder().encode(msg)
            let jsonString = String(data: data, encoding: .utf8)
            print("string : ", jsonString!)

            let msg2 = try JSONDecoder().decode(Message.self, from: data)
            print("Message : ", msg2)

        } catch {
            print("err json")
        }

KeyedContainer

キー値を使ってデータを保存

extension float3: Codable {
    private enum ElementKeys:String, CodingKey {
        case x, y, z
    }
    public func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: ElementKeys.self)
        try container.encode(x, forKey: .x)
        try container.encode(y, forKey: .y)
        try container.encode(z, forKey: .z)
    }
    public init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: ElementKeys.self)
        let _x = try container.decode(Float.self, forKey: .x)
        let _y = try container.decode(Float.self, forKey: .y)
        let _z = try container.decode(Float.self, forKey: .z)
        self.init(_x, _y, _z)
    }
}

jsonに出力した結果↓

{"result":true,"position":{"x":1.2000000476837158,"y":3.4000000953674316,"z":3.4000000953674316}}

SingleValueContainer

1つのデータを送りる

extension float3: Codable {
    public func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        try container.encode(x)
    }
    public init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        let _x = try container.decode(Float.self)
        self.init(_x, 0.0, 0.0)
    }
}

jsonに出力した結果↓

{"result":true,"position":1.2000000476837158}

UnkeyedContainer

配列形式のデータになる

extension float3: Codable {
    public func encode(to encoder: Encoder) throws {
        var container = encoder.unkeyedContainer()
        for v in self {
            try container.encode(v)
        }
    }
    public init(from decoder: Decoder) throws {
        var arr = [Float]()
        var unkeyedContainer = try decoder.unkeyedContainer()
        while !unkeyedContainer.isAtEnd {
            arr.append(try unkeyedContainer.decode(Float.self))
        }
        self.init(arr)
    }
}

jsonに出力した結果↓

{"result":true,"position":[1.2000000476837158,3.4000000953674316,-5.0999999046325684]}

終わりに

Codableは簡単にJsonにエンコード、デコードできるので便利です。

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4