[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 the original and most copied JSON Editor on the web. Use it to view, edit, format, repair, compare, query, transform, validate, and share ...

第一階層の 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 関数で他のと同様に代入してあげれば取得できます。

スポンサーリンク