mike-neckのブログ

JavaかJavaFXかJavaEE(なんかJava8が多め)

Swift で JSON のデコード

f:id:mike_neck:20180609045321p:plain

Swift4 での JSON 文字列からオブジェクトへの変換方法のメモ. もっと詳しく調べたい場合は公式のドキュメントを調べた方がよい.


これからデコードするJSON

{
  "id": 219038
, "name": "James Thunder"
, "password": "s0r23ndsn0q3mf083259"
, "created_at": "2015-04-13T14:20:32"
, "email": [
  {
    "value": "jim@example.com"
  , "primary": true
  }
]
}

JSON にあわせたデータ. protocol Codable に準じた struct で作る

struct User: Codable {
    let id: Int64
    let name: String
    let password: String
    let email: [Email]
    let created_at: String
}

struct Email: Codable {
    let value: String
    let primary: Bool?
}

デコードするコード

let decoder = JSONDecoder()
let user: User = try! decoder.decode(
    User.self,
    from: userJson.data(using: .utf8)!
)

json がスネークケースだけど、オブジェクトのプロパティはキャメルケースにしたい場合は、ネスト enum を作って、 CodingKeys protocol と String を継承させたマッピングを作る.

struct User: Codable {
  let id: Int64
  let name: String
  let password: String
  let email: [Email]
  let createdAt: String

  enum UserCodingKeys: String, CodingKey {
    case createdAt = "created_at"

    case id = "id"
    case name = "name"
    case password = "password"
    case email = "email"
  }
}

なお JSONDecoder の呼び出し方は同じ.


場合によっては配列で返されることもある.

let usersJson = "[\(user)]"

この場合は、 decoder.decode<T>(_ type: T.Type, from data: Data) の呼び出し時の type:[User].self を指定する

let users: [User] = try!
    decoder.decode(
        [User].self,
        from: usersJson.data(using: .utf8)!
)