APIのアドレスに地域コードを指定してURLオブジェクトに仕込む
ここまでに試したのは、ウェブブラウザーのアドレス入力欄に、Wather Hacksの天気情報提供用のAPIのURLに、取得する地域のコードをパラメータとして追加したものを打ち込み、その応答をウェブブラウザーのウィンドウで確認するというものでした。とりあえず、それと同じことをSwiftのプログラムで実行してみましょう。
だいぶ前になりますが、この連載でWebKitを扱った際に、iOSでURLを扱う際には、単なる文字列ではなく、URLというクラスのオブジェクトにする必要があると述べたことをご記憶でしょうか。それについては今回も同じです。そこで、まずベースとなるURLの文字列をbaseStringに、地域のコードをlocationCodeに代入し、それらの文字列を結合したものをURLオブジェクトに変換してtargetUrlに代入してみます。
とりあえず、この状態で実行してみましょう。すると、文字列をURLオブジェクトに変換している行の右端には見慣れない「@」のアイコンが表示されるはずです。そこをタップしてみるとtargetUrlの値のプレビューとして表示されるのは、URLオブジェクトそのものではなく、そのURLにアクセスして返ってきた結果です。
もちろん、まだそのURLにアクセスするプログラムは書いていません。これはSwift Playgroundsのデバッグ機能が気を効かせて、勝手にURLが示すサーバーにアクセスして返答を表示しているのです。残念ながら、その結果をプログラムで利用することはできません。プログラムで結果を取得するためには、もう少しコードを書く必要があります。
なお、ここでは地域のコードとして「140010」を指定していますが、これは「神奈川県横浜市」のものです。全部で142ある地域コードは、上で示したWeather Hacksのページにも説明があるとおり、「全国の地点定義表」(http://weather.livedoor.com/forecast/rss/primary_area.xml)をウェブブラウザーで開くと知ることができます。今回はとりあえず地域コードは固定なので、お住いの地域、あるいは興味のある地域のコードを調べて、それを使ってください。
URLにアクセスして得たJSONを解析して日本語の天気概況情報を取り出す
URLオブジェクトを使って実際にサーバーにアクセスするには、ちょっとだけ面倒な手続きが必要です。というのも、ネットワークアクセスなど時間のかかる処理は非同期で実行しなければならないことになっているからです。非同期というのは「同期しないで」ということで、これは何かの命令を実行するときにその結果が返ってくるのを待たずに、どんどん次の処理を始めるというような処理方法です。結果を待っていると、そこでプログラムの実行が止まってしまうので動きがギクシャクしてしまいます。結果が返ってきたときに何をするべきなのかは、あらかじめ指定しておきます。すると結果が返った際に、一種のコールバックとしてその処理が実行されるというわけです。
URLオブジェクトで示したサーバーからデータを取ってくるには、URLSessionというクラスのdataTaskというメソッドを使います。文法的にはちょっと見慣れないかもしれませんが、このように書くことになっています。
ここでは、エラーなく結果が返ってくると、doの後ろの{}の中が実行されます。そこには、答えとして返ってきたJSON形式のデータをSwiftの辞書に変換し、その中のほんの一部だけを取り出す処理を書いています。ここでも結果はSwift Playgroundsのデバッグ機能を使って表示してみましょう。まずは、返ってきたJSONデータ全体を辞書に変換したものを見てみます。
これはすべて文字列のキーと、不明(Any)な型の値のペアとして構成されています。この表示の中の「>」をタップして掘っていけば、実際のデータを見ることもできます。
次にその中から、「description」というキーに対する値の中の、さらに「text」というキーに対応する値を文字列として取り出してみましょう。この結果もデバッグ機能で見てみます。
これは複雑なデータ構造の端にある値なので、日本語として読むことができます。ほかにどんなデータが含まれているのかは、先に示したWeather Hacksのサイトで確認してください。
JSONは、もともとJavaScriptのオブジェクトをテキストとして書き下すために考えられた形式です。それだけに、JavaScriptでは非常に簡単に扱えるようになっている半面、Swiftで扱うのはなかなか面倒です。SwiftはJavaScriptと異なって型にうるさい言語だからです。このように複雑な構造を持ったJSONをトレースして目的のデータを取り出すには、ひと皮剥くたびに、そのデータの型を指定しなければなりません。
この例は、「forcasts」という配列の最初の要素にある「image」の「url」を文字列として取り出し、その文字列をURLオブジェクトに変換して、やはりSwift Playgroundsのデバッグ機能を使ってその画像を表示しようというものです。
予報が配列になっているのは、今日、明日、明後日の予報を含んでいるからです。この例では、最後に取り出した文字列から生成したURLオブジェクトの先にあるのは「曇り」を表すアイコンだとわかりました。
次回の予定
今回は、ネットワークアクセスということで、手軽に利用できる天気予報のサービスを決めて、そこから基本的な情報を引き出す方法までを示しました。次回からは、これにユーザーインターフェースを加えて、Swift Playgroundsのデバッグ機能に頼らずに、天気予報が普通に表示できるようなものを考えていく予定です。