openweathermapのapiを使用してみます。
使用するapiは「Current weather data」です。
このAPIを使って「現在の東京の天気」情報を取得します。
今回は簡単なテストですのでAPIからのレスポンスデータを加工せずにそのまま(パースしたjson)をデバイスに表示させます。
APIの使い方
「https://api.openweathermap.org/data/2.5/weather」をベースにGET形式でクエリを渡して行きます。
今回は「unit」「appid」「q」の3つを渡します。
実際のリクエストは以下のようになります。
https://api.openweathermap.org/data/2.5/weather?q=tokyo&unit=metric&appid=*******
「*******」箇所はAPIキーになります。
詳しくはCurrent weather dataをご覧ください。
APIクライアント
ApiRequestクラス
カスタムのリクエストを生成するクラスです。
インスタンス生成時にAPIに渡すクエリパラメータの値を設定し、getCreatRequestメソッドでリクエストを取得します。
import Foundation
class ApiRequest{
let baseUrl = "https://api.openweathermap.org/data/2.5/weather"
let city:String
let unit:String
let appid:String
init(_ unit:String, _ appid:String, _ city:String) {
self.city = city
self.unit = unit
self.appid = appid
}
//初期化したプロパティを元にurlを生成
func getCreatUrl() -> URL{
let urlStr = "\(baseUrl)?q=\(city)&unit=\(unit)&appid=\(appid)"
let url = URL(string: urlStr)!
return url
}
//生成したurlを元にリクエストを生成
func getCreatRequest() -> URLRequest{
let url = self.getCreatUrl()
var request = URLRequest(url: url)
request.httpMethod = "GET"
return request
}
}
ViewController
デバイスにAPIのレスポンスを表示させるためのviewを作成、追加しています。
APIとの通信はURLSessionクラスを使用しています。
通信処理はメインスレッドではない別のスレッド(バックグラウンドスレッド)で非同期に行われます。
そのためUIの更新はDispatchQueueクラスを使ってメインスレッドで更新させます。
import UIKit
class ViewController: UIViewController {
//apiのレスポンスを表示するビュー
var label:UITextView!
override func viewDidLoad() {
super.viewDidLoad()
label = UITextView()
label.text = "ロード中"
label.backgroundColor = .yellow
self.view.addSubview(label)
//apiに渡すクエリパラメータの値
let unit = "metric"
let appid = "5581b078ef1a0e69f2ca14dc5e934482"
let city = "Tokyo"
//インスタンス生成
let api = ApiRequest(unit, appid, city)
//リクエストを生成
let request = api.getCreatRequest()
//セッション開始
let session = URLSession.shared //シングルトンのインスタンス
let task = session.dataTask(with: request){ (data, response, error) in
//通信終了後のコールバック処置
guard let data = data else { return }
do {
//jsonデータをパース
let object = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
//print(object!)
//マルチスレッド(並列処理)
//UI部分の更新はメインスレッドで行う
DispatchQueue.main.async {
self.label.text = object?.description
self.label.sizeToFit()
}
} catch let e {
print(e)
}
}
task.resume()
}
override func viewDidLayoutSubviews() {
//レスポンスを表示するビューの設定
let viewWidth = self.view.frame.width
label.frame = CGRect(x: 10, y: 30, width: viewWidth - 20, height: 450)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
表示
["main": {
humidity = 93;
pressure = 1013;
temp = "287.88";
"temp_max" = "289.26";
"temp_min" = "287.04";
}, "name": Tokyo, "id": 1850147, "coord": {
lat = "35.68";
lon = "139.76";
}, "weather": <__NSSingleObjectArrayI 0x6040000194e0>(
{
description = "light intensity shower rain";
icon = 09n;
id = 520;
main = Rain;
}
)
, "clouds": {
all = 75;
}, "dt": 1555248972, "base": stations, "sys": {
country = JP;
id = 8074;
message = "0.005";
sunrise = 1555186225;
sunset = 1555233119;
type = 1;
}, "cod": 200, "visibility": 10000, "wind": {
deg = 180;
speed = "6.7";
}]
● デバイス表示
