Swift Playgroundsで学ぶiOSプログラミング

最低限のコードで天気概況を表示するプログラム

文●柴田文彦 編集●吉田ヒロ

2017年08月21日 17時00分

APIのアドレスに地域コードを指定してURLオブジェクトに仕込む

 ここまでに試したのは、ウェブブラウザーのアドレス入力欄に、Wather Hacksの天気情報提供用のAPIのURLに、取得する地域のコードをパラメータとして追加したものを打ち込み、その応答をウェブブラウザーのウィンドウで確認するというものでした。とりあえず、それと同じことをSwiftのプログラムで実行してみましょう。

 だいぶ前になりますが、この連載でWebKitを扱った際に、iOSでURLを扱う際には、単なる文字列ではなく、URLというクラスのオブジェクトにする必要があると述べたことをご記憶でしょうか。それについては今回も同じです。そこで、まずベースとなるURLの文字列をbaseStringに、地域のコードをlocationCodeに代入し、それらの文字列を結合したものをURLオブジェクトに変換してtargetUrlに代入してみます。

iOSでネットワークにアクセスする際には、URLは文字列ではなくURLクラスのオブジェクトにする必要があります。ここではAPIのURLと地域コードを結合したものをURLオブジェクトに変換しています

 とりあえず、この状態で実行してみましょう。すると、文字列をURLオブジェクトに変換している行の右端には見慣れない「@」のアイコンが表示されるはずです。そこをタップしてみるとtargetUrlの値のプレビューとして表示されるのは、URLオブジェクトそのものではなく、そのURLにアクセスして返ってきた結果です。

Swift Playgroundsでは、URLオブジェクトを作成するだけでその先にあるサーバーの応答をデバッグ機能を使ってプレビューすることができます。これがJSON形式の天気情報です

 もちろん、まだそのURLにアクセスするプログラムは書いていません。これはSwift Playgroundsのデバッグ機能が気を効かせて、勝手にURLが示すサーバーにアクセスして返答を表示しているのです。残念ながら、その結果をプログラムで利用することはできません。プログラムで結果を取得するためには、もう少しコードを書く必要があります。

 なお、ここでは地域のコードとして「140010」を指定していますが、これは「神奈川県横浜市」のものです。全部で142ある地域コードは、上で示したWeather Hacksのページにも説明があるとおり、「全国の地点定義表」(http://weather.livedoor.com/forecast/rss/primary_area.xml)をウェブブラウザーで開くと知ることができます。今回はとりあえず地域コードは固定なので、お住いの地域、あるいは興味のある地域のコードを調べて、それを使ってください。

URLにアクセスして得たJSONを解析して日本語の天気概況情報を取り出す

 URLオブジェクトを使って実際にサーバーにアクセスするには、ちょっとだけ面倒な手続きが必要です。というのも、ネットワークアクセスなど時間のかかる処理は非同期で実行しなければならないことになっているからです。非同期というのは「同期しないで」ということで、これは何かの命令を実行するときにその結果が返ってくるのを待たずに、どんどん次の処理を始めるというような処理方法です。結果を待っていると、そこでプログラムの実行が止まってしまうので動きがギクシャクしてしまいます。結果が返ってきたときに何をするべきなのかは、あらかじめ指定しておきます。すると結果が返った際に、一種のコールバックとしてその処理が実行されるというわけです。

 URLオブジェクトで示したサーバーからデータを取ってくるには、URLSessionというクラスのdataTaskというメソッドを使います。文法的にはちょっと見慣れないかもしれませんが、このように書くことになっています。

作成したURLオブジェクトは、URLSessionクラスのdataTaskメソッドに与えることで非同期処理によってサーバーからの応答を受け取ることができます。ここでは、応答があるとそのJSONデータをweatherDictというSwiftの辞書に変換しています

 ここでは、エラーなく結果が返ってくると、doの後ろの{}の中が実行されます。そこには、答えとして返ってきたJSON形式のデータをSwiftの辞書に変換し、その中のほんの一部だけを取り出す処理を書いています。ここでも結果はSwift Playgroundsのデバッグ機能を使って表示してみましょう。まずは、返ってきたJSONデータ全体を辞書に変換したものを見てみます。

返ってきたJSONデータ全体をとりあえず1つの辞書に変換しています。辞書のキーの型が文字列で、値の型は不明なデータがずらずらと並んでいることがわかります。あとは、この中から必要なデータだけを取り出せばいいのです

 これはすべて文字列のキーと、不明(Any)な型の値のペアとして構成されています。この表示の中の「>」をタップして掘っていけば、実際のデータを見ることもできます。

 次にその中から、「description」というキーに対する値の中の、さらに「text」というキーに対応する値を文字列として取り出してみましょう。この結果もデバッグ機能で見てみます。

辞書の中からdescriptionというキーに対応する値(実際はキーが文字列型の辞書)を取り出し、その中からさらにtextというキーに対応する値を文字列として取り出した結果を、Swift Playgroundsのプレビュー機能で表示してみました。天気概況が読めます

 これは複雑なデータ構造の端にある値なので、日本語として読むことができます。ほかにどんなデータが含まれているのかは、先に示したWeather Hacksのサイトで確認してください。

 JSONは、もともとJavaScriptのオブジェクトをテキストとして書き下すために考えられた形式です。それだけに、JavaScriptでは非常に簡単に扱えるようになっている半面、Swiftで扱うのはなかなか面倒です。SwiftはJavaScriptと異なって型にうるさい言語だからです。このように複雑な構造を持ったJSONをトレースして目的のデータを取り出すには、ひと皮剥くたびに、そのデータの型を指定しなければなりません。

 この例は、「forcasts」という配列の最初の要素にある「image」の「url」を文字列として取り出し、その文字列をURLオブジェクトに変換して、やはりSwift Playgroundsのデバッグ機能を使ってその画像を表示しようというものです。

複数のステップを経て辞書の中から天気予報を表すアイコン画像のURLを文字列として取り出し、その文字列をURLオブジェクトに変換しています。これでアイコン画像にアクセスできるはずです

 予報が配列になっているのは、今日、明日、明後日の予報を含んでいるからです。この例では、最後に取り出した文字列から生成したURLオブジェクトの先にあるのは「曇り」を表すアイコンだとわかりました。

文字列から変換して作成してURLオブジェクトをSwift Playgroundsのプレビュー機能で見てみると、この例では曇りを表すアイコン画像が表示されました

次回の予定

 今回は、ネットワークアクセスということで、手軽に利用できる天気予報のサービスを決めて、そこから基本的な情報を引き出す方法までを示しました。次回からは、これにユーザーインターフェースを加えて、Swift Playgroundsのデバッグ機能に頼らずに、天気予報が普通に表示できるようなものを考えていく予定です。

mobileASCII.jp TOPページへ