気象データの取得
WeatherKitを利用する準備ができた後に、実際にWeatherKitを利用して気象データを取得してみます。
本日の気象データを表示する
WeatherKitでできることを確認するために、取得した気象データを取得して画面に表示します。まずは本日の気象データを確認してみましょう。
import SwiftUI
import WeatherKit // ----①
import CoreLocation
struct ContentView: View {
@State var currentWeather: CurrentWeather? // ----②
var body: some View {
Form {
if let weather = currentWeather { // ----④
Section {
// 気温
Label(weather.temperature.formatted(), systemImage: "thermometer")
// 湿度
Label("\(Int(weather.humidity * 100))%", systemImage: "humidity.fill")
// 日中か夜間か
Label(weather.isDaylight ? "Day time" : "Night time", systemImage: weather.isDaylight ? "sun.max.fill" : "moon.stars.fill")
} header: {
HStack {
Spacer()
// 天気のシンボル
Image(systemName: weather.symbolName)
.font(.system(size: 60))
Spacer()
}
}
}
}
.task {
// 現在の気象データを取得
await getWeather()
}
}
func getWeather() async { // ----③
let weatherService = WeatherService()
let point = CLLocation(latitude: 35.6809591, longitude: 139.7673068) // 東京駅
do {
let weather = try await weatherService.weather(for: point, including: .current) // ----④
currentWeather = weather
} catch {
print(error)
}
}
}
最初にWeatherKitとCoreLocationのフレームワークをインポートします(①)。気象は場所によって変わるので、緯度経度を扱うCoreLocationフレームワークとセットで利用します。
現在の気象データを扱うCurrentWeather構造体を、バインディング変数として用意します(②)。電波状況やサービスの停止などで気象データが取得できないことも考慮してオプショナル型で宣言します。
本日の気象データを取得する処理をgetWeatherメソッドとして定義します(③)。WeatherKitを利用して気象データを取得する際には、非同期構文+do-catch構文を利用します。do-catch構文の中にtryを記述して気象データを取得する処理を作成します。
気象データを取得するには、Apple Weatherの気象データを参照するWeatherServiceクラスのweatherメソッドを利用します(④)。weatherメソッドの引数には、ラベルforで気象データを取得する場所、ラベルincludingで気象データの種類をWeatherQuery構造体で指定します。サンプルではforに東京駅、includingにcurrentプロパティ(現在)を指定しています。
WeatherQuery構造体のプロパティには、currentの他に、daily(日単位)、hourly(時間単位)、minute(分単位)が存在します。現在の気象データは、CurrentWeatherオブジェクトとして得られます。
CurrentWeather構造体では、次のプロパティで気象データの個別項目を参照できます。
| 名前 | 概要 |
|---|---|
| symbolName | 天気のシンボル |
| apparentTemperature.value | 体感温度 |
| cloudCover | 雲量(割合) |
| condition.description | 天気(概要) |
| dewPoint.value | 露点 |
| humidity | 湿度(割合) |
| isDaylight | 日中か |
| pressure.value | 気圧 |
| pressureTrend.description | 気圧傾向 |
| temperature.value | 温度 |
| uvIndex.value | UV指数 |
| visibility.value | 視程 |
| wind.direction.value | 風向 |
| wind.speed.value | 風速 |
| wind.gust.value | 突風 |
天気のシンボルを表すsymbolNameプロパティの値は、iOSのアイコンであるSF Symbolsに相当します。サンプルのように、そのままラベルのアイコンや画像として表示しても構いません。
サンプルでは、現在の天気のシンボル/気温/降水確率/日中か夜間かを表示しています。また、WeatherKitで得られる気象データは、Apple Weatherというシステムで作成した気象データです。実際の天気とは必ずしも一致するとは限りません。
日々の気象データを取得する
前項と同様にして日単位の気象データを取得してみます。WeatherKitでは本日を含め10日間の気象データを取得できます。つまり10日間の天気予報がわかります。10日分の気象データを取得して並べて表示してみましょう。
struct ContentView: View {
@State var dayWeathers: [DayWeather] = [] // ----①
var body: some View {
Form {
ForEach(dayWeathers, id: \.self.date) { weather in // ----③
LabeledContent {
// 天気
Text(weather.condition.description)
// 降水確率
Text("\(Int((weather.precipitationChance*100)))%")
// 天気のシンボル
Image(systemName: weather.symbolName)
} label: {
// 日付
Text(DateFormatter.localizedString(from: weather.date, dateStyle: .long, timeStyle: .none))
}
}
}
.task {
// 日々の気象データを取得
await getWeather()
}
}
func getWeather() async {
let weatherService = WeatherService()
let location = CLLocation(latitude: 35.6809591, longitude: 139.7673068) // 東京駅
do {
let weather = try await weatherService.weather(for: location, including: .daily) // ----②
dayWeathers = weather.forecast
} catch {
print(error)
}
}
}
日単位の気象データを扱うDayWeather構造体の配列をバインディング変数dayWeathersとして宣言します(①)。前項のサンプルと同様に、WeatherServiceクラスのweatherメソッドを、日々の気象データを取得する .daily を引数に実行します(②)。
日々の気象データは、Forecastという分/時/日単位の気象データのコレクションとして得られます。Forecastオブジェクトでforecastプロパティを参照すると、Array型のコレクションを参照できます。
サンプルでは、Array型のDayWeatherオブジェクトを、①で定義した変数dayWeathersに格納しています。dayWeathersをループさせることで、日々の気象データの日付/天気/降水確率/天気のシンボルを表示します(③)。
このようにして10日分の気象データを並べて表示できます。
DayWeather構造体には、CurrentWeatherで説明したプロパティに加えて次のプロパティが存在します。
| 名前 | 概要 |
|---|---|
| highTemperaturet | 日中の最高気温 |
| lowTemperaturet | 夜中の最低気温 |
| precipitationChance | 降水確率 |
| var rainfallAmount | 降水量 |
| var snowfallAmount | 降雪量 |
天気予報でよく利用される項目が参照できます。降水量と降雪量に関しては、該当する天気のときのみ値が返ります。
