乗換案内アプリを作ろう

Webサービスの利用

AppStoreを見ると、電車の乗換案内アプリがたくさんあります。Yahoo!やナビタイム、ジョルダンなど有名な会社のものがある一方で、個人が作っている乗換案内アプリもあります。

乗換案内アプリって個人でも作れるものなんでしょうか?

作れます。

今回は、行き先の駅名を入力したら、今の時刻で乗れる電車を検索する乗換案内アプリを作ってみましょう。自分専用の乗換案内アプリです。

学習内容
・SearchBar(サーチバー)を使ってみる。
・機能追加 データの保存

1.新しいプロジェクトを作る

いつものようにSingle View Applicationでプロジェクトを作ってください。

名前は『norikae』としておきましょう。

2.画面デザイン

『Main.storyboard』をクリックすると、インターフェイスビルダーが表示されます。

部品一覧にある『SearchBar』をドラッグ&ドロップしてください。

画面の最上部に配置し、幅を両サイドまで広げてください。
SearchBarのAutoresizingは伸縮するように設定されているので、変更しなくて大丈夫です。

次に、WebViewをドラッグ&ドロップ。

WebViewの上端はSearchBarの下まで、左右と下端は画面いっぱいに広げてください。
Autoresizingも全方向のマージンを固定、伸縮も縦横有効にしてください。

3.デリゲートを接続する

これまで画面の部品とプログラムを接続するために『アウトレット』と『アクション』を使ってきました。
今回、SearchBarを使うには『デリゲート』というものを使います。
デリゲートは、アクションよりも複雑なことをするときに使う仕組みで、これからもたまに出てきます。

なぜアクションではなくデリゲートなのか。
それはAppleが何らかの理由があって決めたことなので、とりあえずここでは『そういう事になっている』と思っておいてください。

今回は、ビューコントローラーの中に接続するのではなく、上図のようにツリーの方に接続するので注意。
仕組みや動作は徐々にわかると思うので、ここでは手順通りにデリゲートを接続してみてください。

作業後にもう一度Ctrlキーを押しながらSearchBarをクリックして、黒いウィンドウが下のようになっていれば成功です。

WebViewは普通にアウトレットとしてViewControllerと接続してください。
次に、下のプログラムのデリゲート宣言という部分と、デリゲートファンクションの部分を書き足してください。

デリゲート宣言をするとデリゲートファンクションを使えるようになります。
デリゲートファンクションは部品の種類によって色々あり、アクションよりも細かい制御ができるようになっています。
今回は検索ボタンが押されたら、という比較的単純な機能だけを使います。

デリゲートは今後、より高度なアプリを作る時に使うことがあります。今は『デリゲート』という名前だけ覚えておいてください。

4.外部プログラムを利用する

前回に引き続きサポートファイルを使います。

↓前回と同じものですが、なくしてしまった方はダウンロードしてください。なくしてない方は前回のGeneral.swiftを使ってください。

サポートファイルをダウンロード

解凍したらGeneral.swiftを今回のプロジェクトのXcodeのファイル一覧にドラッグ&ドロップしてください。

ファイルの追加画面が↓のように出てきます。『Copy items if needed』にチェックを入れて、右下のFinishをクリックしてください。

これで完了です。

5.Yahoo!乗換案内をアプリ内から利用する方法

今回のアプリではYahoo!乗換案内のWebサービスを利用することで乗換案内アプリを作ります。

では、Yahoo!乗換案内はどのように動いているのでしょうか?

実際に使ってみましょう。Yahoo!乗換案内はコチラ

出発駅と到着駅の名前を入力して、日時や条件を設定して検索ボタンを押すと乗換案内が検索されます。

検索条件ページから、検索結果のページにはURL(Webブラウザでホームページを見る時に必要なアドレス情報)で情報が渡されていて、例えば下のようになっています。

ちょっと『難しそう…』って思ったかもしれませんが大丈夫、一つずつ見ていきましょう。

まず、目立つところで『from=%E9%AB%98%E5%B0%BE%E5%B1%B1%E5%8F%A3』の部分ですが、『%E9%AB…』の部分は駅名が入っています。

『URLエンコード』という処理がされていて人間が読むのは難しいですが、これを『URLデコード』してみると下のようになります。

https://transit.yahoo.co.jp/search/result?flatlon=&from=高尾山口&to=葛西&hb=1&lb=1&al=1&sr=1&ym=201705&d=27&hh=19&m1=4&m2=6&type=1&ws=2&s=0&expkind=1&ticket=ic&datepicker=&kw=葛西&x=95&y=18

エンコードしたものを元に戻すのがデコードです。


コチラでエンコード/デコードができます。

一気に見やすくなった気がしませんか。URLに『%E9%AB…』みたいな感じの文字列が入っている場合は、多くの場合日本語が入っているのでURLデコードをすれば解読できます。

次に分かりやすいのは『&ym=201705&d=27&hh=19&m1=4&m2=6』の部分でしょうか。

どうですか、何を意味するか分かりますか?

そう、日時ですね。ymは年月、dは日付、hhは時間。分はちょっと変わっていて、m1とm2で10の位と1の位に分かれています。

解読すると『2017年5月27日 19時46分』になります。

この日時が何なのかを表すのは次の『type=1』で、1は出発という意味になっています。つまり、ここまでの情報をまとめると、上記のURLは、

『2017年5月27日 19時46分に出発する高尾山口から葛西までの乗換案内を検索してください』という意味になります。

試しにURLの一部(駅名や日時)を変えてブラウザのアドレスバーに入れてみてください。検索結果が変化するはずです。

他にもたくさんのパラメーターがありますので、下記補足で説明します。

補足 その他のパラメーターの意味

他の『hb=1』や『lb=1』などの部分にも意味があります。基本URLの後ろに?が付いて、次に&区切りで多数のパラメーターが並びます。基本URL http://transit.loco.yahoo.co.jp/search/result?
出発駅 from=高尾山口
到着駅 to=葛西
経由駅 via=
新幹線 shin=1 1(有効)、0(無効)
有料特急 ex=1
座席指定 expkind=1
飛行機 al=1
高速バス hb=1
路線バス lb=1
フェリー sr=1
年月 ym=201205 日 d=19 時間 hh=11 分の10の位 m1=1 分の1の位 m2=
時刻タイプ type=1 出発=1 到着=4 始発=3 終電=2
歩く速度 ws=? ゆっくり歩く=4? 少しゆっくり=3 普通に歩く=2 急いで歩く=1
ソート s=0 到着が早い=0 乗換が少ない=2 料金が安い=1
不明につき固定 ost=0
エンコード ei=utf-8
キーワード(到着駅と同じ) kw=葛西
ボタンをクリックした時の座標 x=152 y=29などこれらのパラメーターをコントロールすることで乗換案内の内容を自由に変えられます。これらは、検索条件を少しずつ変えながらどこがどう変わったのかを観察して調べました。

6.乗換案内アプリを作っていきましょう

では実際に現在時刻などを設定して、目的地駅までの乗換案内を表示するアプリを作っていきましょう。

まず、検索バーのデリゲートファンクション冒頭に現在の日時を取得するプログラムを書きます。下記の内容を入力してください。

『General』とは、サポートファイルに含まれていたプログラムです。GeneralのgetNowDateAndTimeというファンクションを呼び出しています。

getNowDateAndTimeは日時の要素をバラバラにして、返り値の『.0(ドットゼロ)~.4まで』に格納して返してくれます。

それらをyearなどの各変数に格納します。

なお、『let year:Int = 』と書かずに『let year = 』としか書いていませんが、型(ここなら:Int)の宣言は省略できます。

getNowDateAndTimeの返り値は整数なので、yearやmonthなども自動的に整数として定義されます。

次に、駅名や日時をURLに組み込むプログラムを書きます。

7.文字列(String)を整形(format)する

文字列を作る方法はいくつかありますが、今回はformatを使います。Lesson7でやりましたね。

今回必要なプログラムは下記の通りになります。

URLの部分はさすがに手入力してもらうのは大変なので、コピペしてください。

https://transit.yahoo.co.jp/search/result?flatlon=&from=葛西&to=%@&hb=1&lb=1&al=1&sr=1&ym=%d%02d&d=%02d&hh=%d&m1=%d&m2=%d&type=1&ws=2&s=0&expkind=1&ticket=ic&datepicker=&kw=%@&x=95&y=18

テンプレートをよく見ると、%dや%@がいくつかありますね。それらがテンプレートの後ろにある変数に置き換えられます。

どこにどういう内容が入るか理解できますか?

では、プログラムを入力していきましょう。

%@や%dが、順番通り日時や駅名を入れていけば乗換案内検索用のURLが完成します。

出発駅は葛西にしていますが、自分がよく使う駅名を入れてみてください。すると、自分専用の乗換案内アプリとして便利に使えるようになります。

補足 %dと%02dの違い
よく見ると『%d』と書かれた部分と『%02d』と書かれた部分があります。『ym=%d%02d』と書かれています。%dは数字がそのまま入ります。2017なら2017です。1なら1です。%02dの部分は、指定された桁数で足らない時は0詰めになります。例えば、%02dで12なら12と入りますが、4なら04になります。1なら01です。%03dなら001、004などになります。『ym=%d%02d』に2017と4を入れれば『201704』になりますが、『ym=%d%d』なら20174になってしまいます。

8.URLをWebViewに渡して読み込ませる

URLの文字列ができたら、それをWebViewに渡して結果を読み込み、表示してもらいましょう。
そのためのプログラムは下記のようになります。

Lesson7でGoogleを表示したのと全く同じです。
URLをリクエストに変換して、『webView』の『loadRequest』というファンクションに渡しています。
これで、しばらくすると結果が表示されます。

そして忘れちゃいけない、キーボードを消す処理。最後のこの1行を追加します。

 

最終的には下のようになります。

では、アプリを実行してみてください。どうですか?

検索窓に行き先の駅名を入れて検索してみましょう。
乗換案内が表示されましたか? 行き先の駅名を変えても正しく動きますか?

余裕があったら、プログラム中のURLを編集して、出発駅や条件を変えたりしてみてください。

9.機能追加 駅名を保存して、次回起動時に読み込むようにする

何度かこのアプリを使っていると不便に感じることが出てきます。
行き先の駅もある程度決まっているのに、アプリを起動するたびに消されると面倒じゃないですか?

そこで、検索時に入力した駅を保存しておいて、アプリが起動する時にそれを読み込んで検索窓に設定するように機能を追加してみましょう。

1.検索窓に入力されたキーワード(駅名)を保存する部分

普通の変数は、アプリを再起動すると元に戻ってしまいます。
再起動したときに再現するためには、データをどこかに書き込まなくてはいけません。
そのために『UserDefaults』という機能を使います。ちょっとした設定やアプリの状態を保存するのに便利な機能です。

↓検索するときのプログラムに下の赤枠内を加えてください。

まず、UserDefaultsの機能を使うために、『ud』という名前を付けて変数として作ります。
次に、『set』というファンクションを使い、『searchBar.text』の内容を保存します。
保存にはキーワードが必要で、今回は『SearchKey』を使います。

最後に『synchronize()』を使ってデータの保存を確定します。
(synchronizeを忘れると、保存したつもりが保存されていないという現象がたまに起きます)

2.サーチバーのアウトレットを作る

次に、サーチバーのアウトレットを作ってください。

検索するときのデリゲートファンクション『searchBarSearchButtonClicked』の中では、searchBarという名前で検索窓にアクセスすることができました。searchBarSearchButtonClickedの引数にあるからです

しかし、外側ではアクセスすることができません。なのでアウトレットを接続する必要があります。

3.viewDidLoadで保存したキーワードを読み込む

1で保存したキーワードを読み込んで検索窓に設定する処理を、viewDidLoadに書きます。

viewDidLoadは画面が表示されるときに自動で呼び出されるファンクションでしたね。

保存のときと同じようにUserDefaultsをudという名前で作ります。

次の行で、保存した時に使ったキーワード『SearchKey』を使ってstringファンクションを呼び出し、保存した検索語句(駅名)を読み込んでいます。

保存したときとキーワードが違うと読み込めません。綴りや大文字小文字の違いに注意してください。

これで保存した駅名が『SearchBar.text』に読み込まれます。つまり、検索窓に前回保存した駅名が設定されます。

実行して動作を確認してみましょう。

駅名を入れて検索後にホームボタン2回押しからアプリを終了し、再度起動して駅名が再現されるか試してください。

完成したプログラム全体を貼っておきます。

10.アプリはこうやって便利にしていきます

アプリは一度作って完成、完全に終わりというわけではありません。

使ってみて、不便なところがあれば改善し、いいアイディアを思いついたら機能を追加していきます。

アプリは自分で使って改善していくことで、より便利になっていきます。便利なアプリを作ればたくさんの人が使ってくれて、場合によっては収入増に繋がります。

ぜひアプリを育ててみてください。


戻る