koogawa blog

iOS、Android、foursquareに関する話題

APIKit + Himotoki + foursquare API でベニューを取得する

これは何

[twitter:@ishkawa] さん作の APIKit と、 id:ikesyo さん作の Himotoki を組み合わせて、foursquare API でベニューを取得したときのメモです。

実行環境

  • Xcode 7.3.1
  • Swift 2.2
  • Carthage 0.11.0
  • APIKit 2.0.1
  • Himotoki 2.0.1

準備

Carthage

ライブラリをインストールするために Carthage を使います。未インストールの場合は Homebrew でインストールします。

$ brew install carthage

アクセストークン取得

foursquare API にアクセスするためのアクセストークを取得します。

一番早いのは API Explorer にアクセスして、そこに表示される oauth_token をコピーする方法です。(本番リリースするアプリには使っちゃダメよ)

https://developer.foursquare.com/docs/explore#req=venues/search%3Fll%3D40.7,-74

image

https://api.foursquare.com/v2/venues/search?ll=40.7,-74&oauth_token=(YOUR_ACCESS_TOKEN)&v=20160529

でベニュー一覧が取得できることを確認します。

実装

サンプルプロジェクト作成

今回は 4sqAPIKitHimotoki という名前にしました。

f:id:koogawa:20160529142148p:plain

APIKit + Himotoki インストール

.xcodeproj ファイルがあるディレクトリに Cartfile を作成します。

github "ishkawa/APIKit" == 2.0.1
github "ikesyo/Himotoki" == 2.0.1

carthage update を実行します。(ちょっと時間がかかる)

$ carthage update
*** Fetching Himotoki
*** Fetching APIKit
*** Fetching Result
*** Downloading Result.framework binary at "2.0.0: A Portable Result"
*** Checking out APIKit at "2.0.1"
*** Checking out Himotoki at "2.0.1"
...

このとき、一緒に Result.framework もダウンロードされます。

update が終わったら、プロジェクトに3つのライブラリを追加します。

f:id:koogawa:20160529142225p:plain

Carthage の使い方は [twitter:@yutat93] さんの記事がとてもわかりやすいです。

データモデル定義

今回使用する /venues/search API のレスポンスは次のようなJSONになっています。

f:id:koogawa:20160529142259p:plain

ベニューのリスト response > venues だけ欲しいので、次の2つのデータモデルを定義することにします。

  • Resp(Response にしたかったが、APIKit の Response クラスと名前が重複するのでこの名前にした)
  • Venue

JSON デコードには Himotoki を使っています。Decodable プロトタイプで必須となる decode メソッドで各プロパティの初期化を行っています。演算子 <| の意味などは Himotokiのドキュメントを参照してください。

Resp.swift

import Himotoki

struct Resp {
    var venues: [Venue]
}

extension Resp: Decodable {
    static func decode(e: Extractor) throws -> Resp {
        return try Resp (
            venues: e <|| "venues"
        )
    }
}

Venue.swift

import Himotoki

struct Venue {
    var id: String
    var name: String
}

extension Venue: Decodable {
    static func decode(e: Extractor) throws -> Venue {
        return try Venue (
            id: e <| "id",
            name: e <| "name"
        )
    }
}

APIリクエスト用の型作成

最初にRequestType プロトコルを継承したプロトコルを作成します。

FoursquareRequestType.swift

protocol FoursquareRequestType: RequestType {

}

RequestType プロトコルに準拠するためには次の5項目を実装する必要があります。

  • typealias Response
  • var baseURL: NSURL
  • var method: HTTPMethod
  • var path: String
  • func responseFromObject(object: AnyObject, URLResponse: NSHTTPURLResponse) throws -> Response

まず、ベース URL を返す実装をプロトコル拡張で持たせます。

extension FoursquareRequestType {
    var baseURL: NSURL {
        return NSURL(string: "https://api.foursquare.com")!
    }
}

v2/venues/search をリクエストするための型を作成します。

struct GetVenueList : FoursquareRequestType {
    typealias Response = Resp

    var method: HTTPMethod {
        return .GET
    }

    var path: String {
        return "/v2/venues/search"
    }

    var parameters: AnyObject? {
        return [
            "ll": "40.7,-74",
            "oauth_token": "(YOUR_OAUTH_TOKEN)",
            "v": "20160529",
        ]
    }

    func responseFromObject(object: AnyObject, URLResponse: NSHTTPURLResponse) throws -> Response {
        return try decodeValue(object, rootKeyPath: "response")
    }
}

これで RequestType プロトコルに準拠できました。

リクエス

実際に foursquare API にアクセスしてみます。

let request = GetVenueList()

Session.sendRequest(request) { response in
    switch response {

    case .Success(let responses):
        self.venues = responses.venues

    case .Failure(let error):
        print(error)
    }
}

リクエストが成功すると response.Success になります。

f:id:koogawa:20160529142525p:plain

所感

最初 Himotoki 独特の演算子に少し戸惑いましたが、慣れてしまうとかなり便利に感じられるようになりました。

APIKit も活発にアップデートが続けられており、作者である ishkawaさんが APIKit の使い方を積極的に発信されているのが嬉しいです。

APIKit + Himotoki とても良さそうです😃

サンプルコード

github.com

リンク