iOS
Swift
Alamofire
Spotify

Spotify APIで楽曲検索(1)

Spotify API を使って、アーティストからアルバムの情報を検索してみます。

search.gif

プロジェクトは GitHub においてあるので参考にしてみてください。

環境
- OS macOS 10.12.6
- xcode 9.2
- swift 4.0.3
- Alamofire 4.7.1

Alamofireのインストール

CocoaPodsのインストール

$ gem install cocoapods

プロジェクトのディレクトリに移動して

$ pod init

を実行。podfile が作成されるので、以下のように編集。

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '10.0'
use_frameworks!

target '<Your Target Name>' do
    pod 'Alamofire'
end

最後に

$ pod install

を実行して Alamofire のインストールは完了。xcode を一旦閉じて、(projectname).xcworkspace を開く。

Spotify API をコール

Client ID と Client Seacret の取得

API を利用するためにはSpotifyアカウントを作成し、My Dashboad からアプリケーションの登録が必要。

"CREATE CLIENT ID" から、必要事項を記入すると、アプリケーション認証に必要な "Client ID" と "Client Seacret" が以下のように表示されるので控えておく。

2018-05-15 23.28.23.png

アプリケーションの認証とアクセストークンの取得

アプリケーションの認証には、全部で3つの方法が 公式ドキュメント にて提供されている。今回は最も単純な "Client Credential Flow" を使って認証を行う。

まずは, 先ほど取得した "Client ID" と "Client Seacret" を Base64 でエンコーディングした値を取得。

$ echo -n {client ID}:{Client Secret} | base64

出力値 Y2I2ZmM2Mj...NzA2Mzk= を控えておく。

次に、Alamofire の request メソッドを使ってAPIへのアクセスに必要なアクセストークンの取得を行う。

import Alamofire

ここで、Cannot load underlying module for 'Alamofire' のエラーが出るがビルドすると消えるので無視。

リクエストの送信先URLを定義。

let tokenURL = "https://accounts.spotify.com/api/token"

先ほど取得したエンコーディングされた "Client ID" と "Client Seacret" の値からヘッダーを定義。

let basicHeader: HTTPHeaders = ["Authorization" : "Basic Y2I2ZmM2Mj...NzA2Mzk="]

パラメータを定義。

let parameters: Parameters = ["grant_type" : "client_credentials"]

requestメソッドによりリクエストの送信を行い、結果をJSONで受け取る。

Alamofire.request(tokenURL, method: .post, parameters: parameters, headers: basicHeader).responseJSON(completionHandler: {
            response in

            var tokenJSON = try! JSONSerialization.jsonObject(with: response.data!, options: .mutableContainers) as! [String : AnyObject]
            var token = tokenJSON["access_token"] as! String

        })

tokenJSONは以下のようになっており、上記のコードでは API へのアクセスに必要な access_token のみを取り出している。

["scope": , "token_type": Bearer, "access_token": BQB79...zPaE, "expires_in": 3600]

Spotify API からアルバム情報の取得

アクセストークンを使って、API へ指定したアーティストのアルバムについての情報をリクエストする。

アクセストークンからヘッダーを定義。

let access_token: HTTPHeaders = ["Authorization" : "Bearer \(token)"]

検索用のリクエストを定義。

let searchURL = "https://api.spotify.com/v1/search?q=john%20mayer&type=album&limit=20"

?以降はq=hoge%20hogeで検索のキーワードを指定、type={track, artist, album, playlist}で検索の種類を指定(今回はアルバムを選択)、limit=20で表示する数の上限を指定している。

今回は John Mayer のアルバムを最大20件取得するようにリクエストの送信を行った。

Alamofire.request(searchURL, headers:access_token).responseJSON(completionHandler: {
        response in

        var searchJSON = try! JSONSerialization.jsonObject(with: response.data!, options: .mutableContainers) as! [String : AnyObject]
    })

searchJSONは以下のような構成になっている。

["albums": {
    href = "https://api.spotify.com/v1/search?query=john+mayer&type=album&offset=0&limit=20";
    items =     (
                {
            "album_type" = album;
            artists =             (
                                {
                    "external_urls" =                     {
                        spotify = "https://open.spotify.com/artist/0hE...xO14";
                    };
                    href = "https://api.spotify.com/v1/artists/0hE...xO14";
                    id = 0hE...xO14;
                    name = "John Mayer";
                    type = artist;
                    uri = "spotify:artist:0hE...xO14";
                }
            );
            "available_markets" =             (
                AD,
                AR,
                ...
                US,
                UY,
                ZA
            );
            "external_urls" =             {
                spotify = "https://open.spotify.com/album/4Dg...TaYBb";
            };
            href = "https://api.spotify.com/v1/albums/4Dg...aYBb";
            id = 4Dgxy95K9BWkDUvQPTaYBb;
            images =             (
                                {
                    height = 640;
                    url = "https://i.scdn.co/image/132...a2c1";
                    width = 640;
                },
                                {
                    height = 300;
                    url = "https://i.scdn.co/image/dac...55e9";
                    width = 300;
                },
                                {
                    height = 64;
                    url = "https://i.scdn.co/image/098...35a7";
                    width = 64;
                }
            );
            name = "Where the Light Is: John Mayer Live In Los Angeles";
            "release_date" = 2008;
            "release_date_precision" = year;
            type = album;
            uri = "spotify:album:4Dg...aYBb";
        }, ...
    };

        limit = 20;
        next = "https://api.spotify.com/v1/search?query=john+mayer&type=album&offset=20&limit=20";
        offset = 0;
        previous = "<null>";
        total = 209;
        }]

受け取ったデータからアルバムのタイトルnameとアートワークimageを取り出す。

if let albums = searchJSON["albums"] as? [String : AnyObject] {
    if let items = albums["items"] {
        for i in 0..<items.count{
            let item = (items as! NSArray)[i] as! [String : AnyObject]
            // album title
            let name = item["name"] as! String
            // album artwork
            let image = (item["images"] as! NSArray)[0] as! NSDictionary
            let imageURL = URL(string: image["url"] as! String)
            let imageData = NSData(contentsOf: imageURL!)
            let mainImage = UIImage(data: imageData! as Data)
        }
    }
}

その他リクエストの詳細な送信方法については こちら を参考に。

以上の手順で Spotify APIからアルバムのタイトルとアートワークの情報を取得することができました。次回は、StoryBoardで取得した情報を表示してみます。