このページの本文へ

オープンデータをAPIで取得してアプリに表示しよう

2015年10月29日 11時00分更新

文●森 巧尚

  • この記事をはてなブックマークに追加
本文印刷

他のサービスやアプリとつながるiOSアプリをSwiftで作成しながら、「アプリの考え方」を習得する本連載。前回は、ネットワーク上のデータをアプリに読み込んで扱う方法について解説しました。今回は実務でも利用することの多いオープンデータをアプリで扱う方法を解説します。

※本連載では、2015年10月時点で最新のXcode 7、Swift 2で解説します。

誰でも自由に利用可能なオープンデータ

オープンデータとは、誰でも自由に入手でき、再利用や再配布のできるデータのことです。公共機関や科学データ、天気データなどがあり、形式はXMLやCSVやJSONなどがあります。

オープンデータの中から今回は、「HeartRails Express」の無料APIをつかって、指定した路線の駅情報を取得して表示しましょう。

HeartRails Expressは、路線/駅名データ等の地理情報を、XML、JSON 形式で無料提供しているサービスです。

「HeartRails Express」

http://express.heartrails.com/api.html

※無料利用には、アプリケーション内に 「HeartRails Express」 のクレジットが必要です。

「駅情報取得API」は「http://express.heartrails.com/api/json?method=getStations」で、駅の情報一覧が取得できます。

ブラウザーに直接

http://express.heartrails.com/api/json?method=getStations&line=JR山手線

と入力するとJSON形式で山手線の駅名データが返ってきます。

データの構造は、「駅情報取得API」の「レスポンスフィールド」で確認できます。

返ってきたJSONデータから階層構造がわかります。

Swiftで試してみよう

APIの階層構造がわかったところで実際にアプリを作ってみましょう。

前回、JSONデータのデメリットは「本当にそのデータがあるかどうかをチェックする」のが大変だと解説しました。今回はJSONデータを解析する「SwiftyJSON」ライブラリーを利用します。

1)SwiftyJSONライブラリーをダウンロードします。

SwiftyJSON-masterをGitHubからダウンロードします。右下にある「Download ZIP」ボタンからダウンロードできます。

ダウンロードしたファイル(SwiftyJSON-master.zip)を解凍すると、「SwiftyJSON-master」フォルダが作成されます。

2)Xcodeのメニュー「File」→「New」→「Project」から「Single View Application」を選択して、新規プロジェクトを作成しましょう。

3)「作成したプロジェクトのフォルダ」を開き、そこに、SwiftyJSON-masterフォルダをドラッグ&ドロップしてコピーします。

4)作成したプロジェクトを開き、コピーしたSwiftyJSON-masterフォルダを開いて、中にある「SwiftyJSON.xcodeproj」ファイルを、ナビゲータエリアのプロジェクトファイルの下にドラッグ&ドロップします。

5)「プロジェクト」→「TARGETS」→「Build Phases」→「Target Dependencies」の「+」ボタンを押して、「SwiftyJSON iOS」を選択して、「Add」ボタンを選択します。

これで、このプロジェクトでSwiftyJSONを使えるようになりました。

6)Info.plistに例外処理をし、HTTP通信を可能にします。

iOS 9から、ATS(App Transport Security)というセキュリティ機能が付きました。ATSが有効のときは、HTTP通信ができません。Info.plistに例外としてドメインを設定し、そのドメインとHTTP通信できるようにします。

  1. [Info.plist]を選択して、[Add Raw]メニューで1行追加し、Keyに[NSAppTransportSecurity]を入力、Typeを[Dictionary]にします。
  2. 三角アイコンを下向きにして、[Add Raw]メニューで1行追加し、Keyに[NSExceptionDomains]を入力、Typeを[Dictionary]にします。
  3. 三角アイコンを下向きにして、[Add Raw]メニューで1行追加し、Keyに[express.heartrails.com]を入力、Typeを[Dictionary]にします。
  4. 三角アイコンを下向きにして、[Add Raw]メニューで1行追加し、Keyに[NSTemporaryExceptionAllowsInsecureHTTPLoads]を入力、Typeを[Boolean]、Valueを[Yes]にします。

これで、「express.heartrails.com」とHTTP通信できるようになりました。あとは、いつものようにアプリを作っていきます。

7)画面に[Button]と[textView]と[Label]を配置して、アプリ画面を作ります。

「Main.storyboard」を選択し、右下のライブラリーから[Button]と[textView]と[Label]をドラッグ&ドロップして配置します。Labelには「情報:HeartRails Inc.」と書きます。右下の「|△|」ボタンを押して、「Reset to Suggested Constraints(自動レイアウト設定)」を選択します。

Main.storyboardの仮画面の中央にボタンを配置しただけでは、縦長のiPhone画面で見るとボタンが端に表示されてしまいます。自動レイアウト設定をすることで、縦長の画面でも中央に表示されます。

8)[textView]に名前をつけてコントロールします。

メニューで「View」→「Assitant Editor」→「Show Assistant Editor」を選択して、「アシスタントエディター」を表示し、キーボードのcontrolを押しながら、textViewをViewController.swiftへドラッグして、名前を「myTextView」とします。

ViewControll.swiftにコード、


@IBOutlet weak var myTextView: UITextView!

が追加されます。

9)ボタンが押されたときに実行される関数を作ります。

ボタンが押されたときの命令を記述するための関数を作ります。

キーボードのcontrolを押しながら「Button」をViewController.swiftへドラッグし、「Connection」を「Action」に切り換えてボタンを押したとき実行する関数を作ります。関数名は「tapBtn」にします。

10)ViewController.swiftに、プログラムを記述します。

ボタンが押されたときに、heartrailsからJSONデータをダウンロードして解析し、アプリに表示プログラムを記述します。

取得するAPIのURLを用意して、「sendAsynchronousRequest」で非同期ダウンロードを実行します。

例えば、JR山手線の駅名を取得するには「http://express.heartrails.com/api/json?method=getStations&line=JR山手線」となります。路線名は「東京メトロ銀座線」「JR大阪環状線」など指定できますが、URLに日本語が含まれるのでUTF8にURL エンコードします。(18行目)

データの読み込み完了の合図が来たら、JSONに変換します。

データの階層構造を参考にして解析します。

路線名は、json["response"]["station"][0]["line"]

その路線に含まれる駅名は、json["response"]["station"][id]["name"]

で取り出すことができます。

取り出したデータを「myTextView」に表示します。

記述したプログラムは以下の通りです。


// SwiftyJSONを使うのでimport
import SwiftyJSON
class ViewController: UIViewController {
    @IBOutlet weak var myTextView: UITextView!

    @IBAction func tapBtn(sender: AnyObject) {
        let URLstr = "http://express.heartrails.com/api/json?method=getStations&line=JR山手線"
        // 日本語入りのURLなので、UTF8形式に変換する
        let encodeURL:String = URLstr.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!
        if let url = NSURL(string: encodeURL) {
            let request = NSURLRequest(URL: url)
            // データの読み込みが終わったら dispStationsを実行
            NSURLConnection.sendAsynchronousRequest(
                request,
                queue: .mainQueue(),
                completionHandler: dispStations)
        }
    }
    // 表示するメッセージを入れる変数
    var msg:String = ""
    // 返ってきたJSONデータを解析して駅名表示
    func dispStations(res: NSURLResponse?, data: NSData?, error: NSError?){
        if error == nil {
            // JSONデータに変換する
            let json = JSON(data:data!)
            // 路線名を取得
            let linename = json["response"]["station"][0]["line"]
            msg += "路線名=\(linename)\n"
            // 路線内の各駅名を取得
            let linedata = json["response"]["station"]
            for id in 0..<linedata.count {
                let name = linedata[id]["name"]
                msg += "駅[\(id)]=\(name)\n"
            }
            // 駅名リストを表示
            myTextView.text = msg        }
    }
//(中略)

ボタンを押すと、JR山手線の駅名が「textView」に表示されます。

今回は外部 APIを取得し、ライブラリーを使って解析する方法を紹介しました。

プログラムは、自分だけでもすべてを作れますが、他の人が作ったデータやライブラリーを利用して作ると、手間がだいぶ省けます。保守され続けているライブラリーは、自分で作るよりも機能が豊富で、安全な場合もあります。

「いつかは自分もライブラリーを作る側になれたら」を目標に利用したいですね。

この連載の記事

一覧へ

この記事の編集者は以下の記事をオススメしています