ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。
-
今日の天気情報にコンテキストをもたらす
WeatherKitを利用すると、種類別降水量、高度別雲量、最大風速など、詳細な天気予報データを取得できます。1日の時間帯別に天気データを集計し、気温や降水量の大幅な変化を予測する方法をご紹介します。AppleのHistorical Comparisonsデータセットを使用して現在の天気と過去の天気を比較したり、世界各地の過去の天気データを調べたりすることができます。AppleのSwift APIとREST APIを使用し、これらすべてを迅速に実行する方法も確認しましょう。
関連する章
- 0:00 - Introduction
- 1:10 - Richer forecast details
- 10:03 - Highlight weather changes
- 14:10 - Faster data transfer
リソース
- Forum: Maps & Location
- Request authentication for WeatherKit REST API
- WeatherKit
- WeatherKit REST API
関連ビデオ
WWDC22
-
ダウンロード
こんにちは Sidyです Weatherチームの ソフトウェアエンジニアです このビデオでは WeatherKitに 今年導入された 素晴らしいアップデートをご紹介します
WeatherKitの基盤は Apple Weather Serviceです 使いやすいプライバシー重視のAPIにより 非常にローカルな地域状況を反映した 正確な気象データを提供します また WeatherKitは Apple独自の 天気アプリのコアであるだけでなく このキットのSwift APIやREST APIが 様々なアプリの開発に利用されています Carrot Weather、(Not Boring) Weather、 DuckDuckGoなどで利用され ユーザーへの重要な気象情報の提供に 貢献しています 今年Appleは WeatherKitの様々な機能を強化し さらなる進化を実現しました 1つ目は 降水量や高度別雲量などの 詳細情報の予測を 充実させたことです 2つ目は コンテキストを考慮して 今後予測される天気の変化を ハイライトする機能の追加です 3つ目は バイナリ形式のサポートの追加による データ転送の高速化です 本ビデオでは これらの改善点のそれぞれについて アプリへの実装方法も含めて説明します まずは より充実した 予測の詳細情報についてです
WeatherKitは 複数の優れたAPIで構成されています 各地域でどのデータセットを利用できるか 情報を提供するAvailability APIや データソースの帰属情報を提供する Attribution APIのほか 発生中の重大な気象現象について 詳細情報を提供する Active Alert APIがあります しかし 最も重要なのはWeather APIです このAPIは 最も重要な部類の 気象データを提供します 現在の気象状況 分ごとの降水量 時間ごと および日ごとの 10日分の天気予報 気象警報などです
今年 これらの情報を さらに充実させるために 現在の状況と時間ごと/日ごとの予報に より詳細な情報を追加します
従来も 現在の状況として 気温 風速 UV指数など その時点の詳細な気象情報が 表示されましたが このたび 高度別雲量などの より詳細な 情報を追加できるようになりました この機能強化は 時間ごとの予報にも適用されます 時間ごとの雲量予報を追加して 高度別の違いなどの詳細も含め 確認できるようになります Appleの天気アプリと同様に 時間ごとの降水量も表示できます
また 日ごとの予報のクエリは 最も重要な機能強化となります 湿度の高低などの きめ細かい日ごとの予報を 簡単にアプリに追加できるようになったほか 一日を昼と夜の時間帯に分けて それぞれの天気予報を 表示することもできます
次に 時間ごとの降水量データを アプリに表示する方法を Swiftを使用した例で説明します
最初に少し時間を取り CLLocationにExtensionを追加します これにより この例と以降のSwiftによる例で 参照する場所として ニューヨークを参照するのが 容易になります
降水量データの取得は簡単です まず データの取得先の 場所を渡す必要があります
次に データの粒度を設定します 今回は時間ごとにするので .hourlyクエリを指定します
最後に 時間ごとの予報のための precipitationAmountプロパティを 使用します WeatherKitの ほかのすべての機能と同様に これらのプロパティには REST APIによりアクセスできます 先ほどの例を REST APIで実装する方法をお見せします
WeatherKit APIがホストされているのは weatherkit.apple.comなので これをRESTful URLパスとして渡します 次に APIのバージョンを表す パラメータを付加します 現時点のリリースはバージョン2です APIを指定しますが この場合はWeather APIです 続けて ロケールを表すパラメータを追加します データを取得するロケールです この例では アメリカ英語のen-USですが iOSがサポートする あらゆるロケールを選択できます サポート対象外のロケールを渡すと デフォルトのレスポンスとして en-USが返されます データを取得したい場所の 座標も指定します この例では Swiftの場合と同様に ニューヨーク市です 最後に 取得するデータセットを指定します この例では 時間ごとの予報です 予報を取得する時間の範囲にも 様々な選択肢があります この例では 説明を簡素化するために 現在の時刻にしますが
最大240時間の予報を リクエストすることもできます
なお 範囲を指定しない場合 WeatherKitのデフォルト値は24時間で 開始時刻は現在です relativeHourlyのクエリパラメータを 使用している点も重要です これにより Apple Weather Serviceが 入力されたタイムゾーンに基づいて 予報の開始時間と終了時間を 正確に計算できます また ご存じかとは思いますが Apple Weather Serviceを利用するには 認証Bearerを生成する必要があります では 結果を見てみましょう
指定したURLに対しGETを発行すると forecastHourlyキーにホストされた オブジェクトが返されます
オブジェクトには一連の 時間ごとの予報が含まれ 各時間の予報には precipitationAmountという 名前のものを含む 複数のプロパティがあります これは 先ほどのSwiftプログラムと同様です
天気をチェックする際 ユーザーは気象パターンの変化に 注目しています 天気の大きな変化は 行動の予定に 影響する可能性があるからです
天気の変化を コンテキストに基づき 事前に把握できることは重要です このことを念頭に Weather APIに まったく新しいクエリを2つ追加しました
それがChangesと Historical Comparisonsです Changesから確認しましょう Changesクエリは 現在以降の気温と降水量の 変化の情報を提供します 大きな気温の上昇/低下や 降雨量の増加/減少など 対象となる 現在以降の大きな変動の 推定発生時刻などです
天気アプリは現在 このクエリを使用して 現在以降の気温の変化を ユーザーに表示しています
このChangesクエリを 皆さんも ご自身のアプリで使えるようになりました その方法をご紹介します 対象の場所は先ほどと同じで ニューヨーク市です 天気の変化を .changesクエリを使って取得します 変化のリストが返されるので 明日発生するもの以外は すべてフィルタで除外します このユースケースを表現しやすいように Dateの構造を拡張し isTomorrowをプロパティに 指定できるようにしています 次のステップでは 気温低下の変化のみを含む配列に 結果をマッピングします 最後に 変化がある場合で その変化に気温低下が含まれる場合には ユーザーに対し 適切なメッセージが 表示されるようにします
これをRESTで実現するには weatherChangesデータセットを指定します なお このユースケースでは 常に情報が返されます 天気の大きな変化が 近い将来に予測されない場合も その情報を返します 理解をさらに深めていただくために 出力例を見てみましょう 先ほど 天気の変化の情報を取得する GETリクエストを発行して データが返されました WeatherChangesオブジェクトが 通常想定される通り weatherChangesキーの 後にあります
変化のリストのラッパーオブジェクトで changesプロパティに データが格納されています
変化にはそれぞれ 予報における 変化の開始日と 終了日があります 最後に 発生が予測される 変化のタイプがあります この例の1つ目の変化は 指定された時間の範囲内に 最高気温の上昇が予測されることを 示しています
状況の変化は 気温低下を示す場合もありますし 変化が予測されない場合 このフィールドには 「steady」のマーカーが入力されます
天気の変化は コンテキストのもとで 把握するのが効果的です そこで今回導入したのが Historical Comparisonsクエリです
Historical Comparisonsを使うと 過去50年以上にわたり 収集されたデータに基づき 今日の天気を過去の平均と比較できます 結果は 平均値との差が大きい順に 表示されます
Historical Comparisonsクエリは現在 天気アプリで使用されています 今日の最高気温の 過去の平均値との差を表示します Weather APIのこのクエリは 使い勝手も優れています 使い方を説明するために 楽しいコードスニペットをご紹介します Swiftでの気象データのリクエストは .historicalComparisonsクエリを 含めるだけで実行できます 先述の通り リストの表示順は 平均値との差の大きさに従います
トレンドからの大きな偏差が特定されたので 出力し ユーザーに通知できます
REST APIを使用する場合 historicalComparisons データセットのみを含めます Swiftの場合と同様に 平均値との差が大きい順に並べられた 比較結果のリストが返されます
このリクエストの出力を見てみましょう
結果のオブジェクトは historicalComparisonsキーの下に格納され 比較結果のリストが含まれています
各比較結果には トレンドを計算するための条件があります
次は 条件の現在の値で
ベースライン値が続きます この値は トレンド計算の方向性に関する コンテキストを提供します
偏差のタイプもあります このフィールドは偏差の程度を示します この例では 偏差は正常範囲内です normal以外の値はhigher、much higher、 lower、much lowerです
baselineTypeは ベースライン値を 設定するために使用されている 統計的手法を示します この例では 平均を使用します これ以外に 中央値なども使用できます このフィールドの値は 統計的推論の手法を 更新した場合 変更される可能性があります
最後の項目は 条件に基づいて計算した 平均値に対応する ベースライン値を設定した日付です
以上のような Apple Weatherに導入された Weather APIの各種の機能強化により 現在の予報がより充実したものになり それが アプリ内において ユーザーに 様々な観点に基づく有益な予報を 提供できることにつながります 次は WeatherKitによって得られる 豊富な気象情報を 世界規模の過去のデータという コンテキストのもとで 活用することについてお話しします
今日 天気予報において 優れた体験を提供するには 天気を 気候現象との関連において 理解することが不可欠になっています 気候変動に対する意識が 高まっているだけでなく 特定の地域の長期的な気象パターンを 総合的に理解することで イベントや休暇の計画を かなり早期に立てることができます
このような予報がやりやすくなるように 気象に関する広範かつ詳細な 過去の統計データを提供する新しいAPIとして Statistics APIを導入しました Statistics APIの新しい2つのクエリは Historical AveragesとDaily Summariesで Historical Averagesを使うと 1970年1月1日以降の記録に基づく 気温と降水量の 長期間の平均データを取得できます データの粒度は時間ごと 日ごと 月ごとを選択できます 例えば 天気アプリではこのAPIを利用して 月ごとの平均降水量を表示し 次の休暇の予定を立てる際 雨の多い時期を避けられるよう 便利な情報をユーザーに提供しています それでは アプリにおいて 統計データを 取得する方法を説明します
これは 月ごとの統計データを取得する Swiftを使用した実装例です シンプルに WeatherServiceの monthlyStatistics関数を 呼び出します 開始月と終了月を指定します グレゴリオ暦に従い 「1」は1月 「12」は12月を表します
使用するクエリの種類を指定します この例では降水量です
結果が出たら 月ごとにキーが付与された辞書に グループ化します
REST APIを使用する場合 monthlyのStatictics APIを呼び出します データセットとしてprecipitationを渡し 開始月と終了月を指定します これで 月ごとの平均値のリストが返されます
次に 出力を見てみましょう
MonthlyWeatherStatistics オブジェクトでは 平均値の計算のための ベースラインの開始日が記述されます 月ごとの平均値のリストは monthsプロパティにホストされます
取得したのは降水量だけなので データはこれだけです precipitationオブジェクトには Apple Weather Serviceから取得された 月ごとの平均データが含まれています 最後に 該当する月の インデックスである1~12の数値が 表示されます
Statistics APIを使えば 2021年8月1日以降の 過去の任意の日の 天気の概要も取得できます
概要には 最高気温と最低気温のほか 降水量や降雪量も含まれます
天気アプリはこの概要を使用して 過去30日間に降水量が どのように累積しているか表示し 今日の状況を把握するための コンテキストを提供します
Swiftでこのデータを取得する方法を 見てみましょう
ここでは Swiftを使用して 降水量に関する 過去30日間の 天気の概要データを取得します
データ取得の期間は 30日前から現在までに指定します なお thirtyDaysAgoは Dateにおいて定義した カスタムのExtensionです
クエリとして降水量を含めています データを取得できたので ユーザーに情報として提供します この例では 降水量のみを リクエストしていることに 再度注意してください REST APIを使う場合 summary/dailyのパスを呼び出します 次に Swiftの例と同様に データセットをprecipitationに絞り込みます 最後に 受け取るデータの 開始日と終了日を指定します 一連の日ごとの概要が結果として返されます 概要には通常 気温と降水量のデータが含まれます なお リクエストしたのは降水量のみなので それ以外の値はすべてゼロです
このように Apple Weather Serviceでは 過去との関連性をより詳細に考慮して 現在の天気を理解するための モデルの構築に向けて 膨大なリソースを投資しています
これらのモデルで算出されるデータが 今回のリリースにより利用可能になります 皆さんに この新しい充実したデータを アプリで活用していただくのが楽しみです
とはいえ これほど膨大な過去の気象データを 取得するには コストがかかります そこで データ処理量の多いAPIでの 気象データの取得を 簡単にするための対策を講じています 今回のリリースで導入された FlatBuffersのサポートにより WeatherKitでの気象データの取得は かつてないほど高速化しました FlatBuffersを利用すると 同規模の圧縮済みJSONファイルと比較して ペイロードサイズを最大25%削減できます また 解析の所要時間も JSONと比較して最大90%短縮されます
Swift APIを使用している場合 この最適化を無料で利用できます REST APIを使用している場合 オプションとして利用でき Acceptヘッダを指定する必要があります
これで 従来なかったほど 大量のデータを取得しつつ ペイロードのサイズも抑制できます
WeatherKitの解説は以上です 本セッションの内容を簡単にまとめましょう 従来の多彩な優れた機能に加えて 現在の天気や 時間ごと/日ごとの天気の予報で よりきめ細かい情報が提供されます 高度別雲量などの詳細情報が得られ 降水量、湿度、視界の情報も より充実しています Changesおよび Historical Comparisonsのクエリと まったく新しいStatistics APIが導入され FlatBufferのサポートが追加されました
皆さんがこれらの機能を利用して 生み出す革新に期待しています すでにWeatherKitを使用中なら 予報の一層の充実に向けて 今回のリリースで提供される 追加のデータポイントをご活用ください 天気の大きな変化に関する予報を ユーザーに継続的に提供することもできます また 膨大な過去のデータにも 容易にアクセスでき ユーザーは より総合的な観点から 現在の天気状況を把握できます REST APIを使用する場合 新しいFlatBufferによる処理を 活用するのがおすすめです WeatherKitを初めて使用される方は WWDC22の「Meet WeatherKit」も 参考にして さっそく試してみてください
ご視聴ありがとうございました
-
-
2:40 - Fetch Precipitation Amount
import CoreLocation import Foundation import WeatherKit extension CLLocation { static var newYork: CLLocation { CLLocation(latitude: 50.710, longitude: -74.006) } } let hourlyPrecipitation = try await WeatherService() .weather(for: .newYork, including: .hourly) .map(\.precipitationAmount)
-
3:25 - Fetch Precipitation Amount (REST)
https://weatherkit.apple.com/api/v2/weather/en-US/40.710/-74.006?dataSets=forecastHourly&relativeHourlyStart=0&relativeHourlyEnd=1&hourlyRelativeTo=now&timezone=America/New_York
-
6:05 - Weather Changes
import CoreLocation import Foundation import WeatherKit extension Date { var isTomorrow: Bool { return Calendar.current.isDateInTomorrow(self) } } let changes = try await WeatherService() .weather(for: .newYork, including: .changes) let lowTemperatureChanges = changes? .filter(\.date.isTomorrow) .map(\.lowTemperature) if let lowTemperatureChanges, lowTemperatureChanges.contains(.decrease) { // Lower temperatures expected tomorrow }
-
6:43 - Weather Changes (REST)
https://weatherkit.apple.com/api/v2/weather/en-US/40.710/-74.006?dataSets=weatherChanges
-
8:17 - Historical Comparisons
import CoreLocation import Foundation import WeatherKit let mostSignificant = try await WeatherService() .weather(for: .newYork, including: .historicalComparisons)? .first switch mostSignificant { case .highTemperature(let trend), .lowTemperature(let trend): // Display temperature trend break case .some, .none: break }
-
8:36 - Historical Comparisons (REST)
https://weatherkit.apple.com/api/v2/weather/en-US/40.710/-74.006?dataSets=historicalComparisons
-
11:11 - Monthly Statistics
import CoreLocation import Foundation import WeatherKit let averagePrecipitation = try await WeatherService() .monthlyStatistics( for: .newYork, startMonth: 1, endMonth: 12, including: .precipitation ) let averagePrecipitationAmountsPerMonth = Dictionary( grouping: averagePrecipitation, by: \.month )
-
11:41 - Monthly Statistics (REST)
https://weatherkit.apple.com/api/v2/statistics/monthly/40.710/-74.006?dataSets=precipitation&start=1&end=12
-
12:52 - Daily Summary
import CoreLocation import Foundation import WeatherKit extension Date { static var thirtyDaysAgo: Date { return Calendar.current.date(byAdding: .day, value: -30, to: .now)! } } let pastThirtyDaysSummary = try await WeatherService() .dailySummary( for: .newYork, forDaysIn: DateInterval(start: .thirtyDaysAgo, end: .now), including: .precipitation ) .first if let pastThirtyDaysSummary { // We have a daily weather summary for each day in the past 30 days }
-
13:22 - Daily Summary (REST)
https://weatherkit.apple.com/api/v2/summary/daily/40.710/-74.006?dataSets=precipitation&start=2024-05-12&end=2024-06-10
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。
クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。