[swift]alamofireとswiftyjsonを使ってAPIからデータを取得する

一つ前の投稿でSalesforceへ接続出来たが、HTTP通信の部分とJSONへのパース部分はライブラリを使うのがデファクトスタンダードになりつつある、という情報を仕入れたので試してみる。

インストール

インストールするライブラリは以下の2つ。

  • Alamofire
  • SwiftyJSON

Alamofire-SwiftyJSONというライブラリも同時に使用している紹介記事が多かったのだが、インストールしてみると以下の様な警告が出た。

Alamofire-SwiftyJSON has been deprecated in favor of AlamofireSwiftyJSON

気になって調べてみると、以下の様なページが。

機械翻訳にかけてみると、どうやらAlamofire-SwiftyJSONはAlamofireの古いバージョンである、1.3を使うようになっており、1.3はSwift2に対応していいない。なので、Alamofireの新しいバージョンをインストールするためには直接Githubのリポジトリを指定してやる必要がある、とのことのよう。

今回は特に使わなくても大丈夫だったのでインストールはしないでおいた。

Podfileには以下を追加。

1
2
pod 'Alamofire'
pod 'SwiftyJSON'

$ pod updateでインストールした。

利用

前回のアクセストークン取得の際のコードは以下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
let URL = NSURL(string: SF_LOGIN_URL + "/services/oauth2/token")
let req = NSMutableURLRequest(URL: URL!)
req.HTTPMethod = "POST"
let paramString = "grant_type=password&client_id=" + SF_CLIENT_ID + "&client_secret=" + SF_CLIENT_SECRET + "&username=" + SF_USERNAME + "&password=" + SF_PASSWORD
req.HTTPBody = paramString.dataUsingEncoding(NSUTF8StringEncoding)

let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: configuration, delegate: nil, delegateQueue: NSOperationQueue.mainQueue())

let task = session.dataTaskWithRequest(req, completionHandler: {
    (let data, let response, let error) -> Void in
    do{
        let json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.AllowFragments) as! NSDictionary
        print(json)
    }catch{
        print("error")
    }
})
task.resume()

import

ライブラリを読み込むために、ファイルの冒頭にimportを追加しておくこと。

1
2
import Alamofire
import SwiftyJSON

HTTP通信

通信は、responseJSONを使う。
少し前にAlamofireの仕様変更があったらしく、エラーハンドリングの方法が変わったよう。

通信部分と結果だけ記述するとこんな感じ。

1
2
3
4
5
Alamofire.request(.POST, URL!, parameters: parameters)
    .responseJSON { response in
          print(response.result)
          //SUCCESS or FAILURE
}

エラーハンドリング用に分岐させるとこうなる。

1
2
3
4
5
6
7
8
9
Alamofire.request(.POST, URL!, parameters: parameters)
    .responseJSON { response in
        switch response.result {
        case .Success(let value):
            print("value: \(value)")
        case .Failure(let error):
            print(error)
        }
}

返ってくるエラーはErrorTypeの型になっており、前回の記事と同じ取扱で大丈夫だった。

JSONへパース

取得した値をJSONへパースするには、以下だけでいける。

1
let json = JSON(data)

また、文字列への変換もプロパティで用意されている。

1
let str:String = json["token"].string

実に簡単。

完成

アクセストークンを取得する部分だけ書き換えたものコードは以下のようになる。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
let URL = SF_LOGIN_URL + "/services/oauth2/token"
let parameters = [
    "grant_type":"password",
    "client_id":SF_CLIENT_ID,
    "client_secret":SF_CLIENT_SECRET,
    "username":SF_USERNAME,
    "password":SF_PASSWORD
]

Alamofire.request(.POST, URL, parameters: parameters)
    .responseJSON { response in
        switch response.result {
        case .Success(let value):
            let json = JSON(value)
            print(json)            
            
            //let access_token = json["access_token"].string
            //let instance_url = json["instance_url"].string
            //let token_type = json["token_type"].string
            
        case .Failure(let error):
          print("error")
        }
}

ヘッダ

ちなみにヘッダの指定は以下のようにしてアクセストークンを送れた。

1
2
3
4
5
6
let headers = [
    "Authorization": "\(self.token_type) \(self.access_token)"
]
Alamofire.request(.POST, URL, parameters: parameters, headers: headers)
  .responseJSON { response in
      (略)

まとめ

コードはそこまで劇的に減るわけではないが、すっきりした。
なによりパラメータの指定や、JSONの取り扱いがかなり見やすく簡単になったと思う。
特に理由がなければライブラリを使えば良い気がする。

参考

   このエントリーをはてなブックマークに追加