[Xcode Swift] ObjectMapperでJSON形式のデータをオブジェクトにマップする

広告:超オススメUnity Asset
  広告:超オススメUnity Asset

以前、Unityで同じようなことをやったのですが、今度は、Xcode(Swift)での話です。

CocoaPodsでObjectMapperを組み込む

現在、Xcode 8.2.1 + Swift3の環境です(2017.7)。

pod 'ObjectMapper', '~> 2.2'

正しくインストールされると、import ObjectMapper も認識され使えるようになります。 

例として、Google Places API Web Service  で取得したPlacesの結果JSONをXcodeへ読み込んでマップしてみようと思います。JSONは以下のような感じになります。JSON Editor Online では、JSONをオブジェクトのツリー構造で表示してくれるので、マップする際に見やすくて便利です。

JSON Editor Online is a web-based tool to view, edit, format, repair, compare, query, transform, validate, and share your JSON data.

第一階層の results にPlacesの結果が配列になっている状態です。このJSONの中から必要な情報だけをマップしてみます。

クラスを用意して、JSONデータをマップする

第一階層からは、status と results を取り出し、results は、 Result クラスの配列になるようにしておきます。Result クラスでは、それ以下にある、id 、name 、place_id を取り出し、さらにネストされている geometry.location.lat と geometry.location.lat も同じプロパティとして扱おうと思います。lat や lng は実際のJSONの階層とは異なる状態となっている感じです。マップするために使うクラス定義は、GooglePlacesMappableClassBox.swift に以下のような感じで詰め込んでおきました。

import UIKit
import ObjectMapper

class GooglePlacesMappableClassBox: NSObject {

}

class Result: Mappable {
    var id: String?
    var name: String?
    var place_id: String?
    var lat:Double?
    var lng:Double?
    
    required init?(map: Map) {
    }
    
    func mapping(map: Map) {
        id <- map["id"]
        name <- map["name"]
        place_id <- map["place_id"]
        lat <- map["geometry.location.lat"]
        lng <- map["geometry.location.lng"]
    }
}


class JSONObj: Mappable {
    var status:String?
    var results:Array<Result>?
    
    required init?(map: Map) {
    }
    
    func mapping(map: Map) {
        status <- map["status"]
        results <- map["results"]
    }
}

実際にJSONを読み込んで(読み込み自体の記述は省略します。読み込んだJSON文字列は「jsonStr」に入っているとします)、「import ObjectMapper」しているコードで

let jsonobj = Mapper<JSONObj>().map(JSONString: jsonStr)

します。すると、jsonobj?.status に「OK」のような文字列が入り、jsonobj?.results が Result オブジェクトの配列になっていることが確認できると思います。jsonobj?.results?[0].lat を見てみると最初のオブジェクトの lat の値が入っているはずです。他にも必要なプロパティがあったら、Result クラスでメンバ変数を作り、 mapping 関数で他のと同様に代入してあげれば取得できます。

スポンサーリンク