WWDC Quick Look 💓 By SwiftGGTeam
Bring context to today's weather

Bring context to today's weather

元の動画を見る

ハイライト

WeatherKit に Changes と Historical Comparisons の 2 種類のクエリが追加され、天気 app を「数字の表示」から「天気変化の解釈」へ進化させられます。


主要内容

天気 app を開くと、通常は気温、湿度、風速などの数字が表示されます。ユーザーは自分で判断する必要があります。今日は昨日より寒いか?明日急に冷え込むか?ユーザーに自分で比較させる体験は、データ提示の失敗です——app はデータを持っているのに、解釈を代わりにしてくれません。

今年の WeatherKit の更新は、この課題に直接応えます。新しい Changes クエリは今後の気温・降水変化を返し、変化が起きる時間帯と方向(上昇/下降/安定)を含みます。Historical Comparisons クエリは現在の天気を 50 年以上の歴史的平均と比較し、結果を偏差の大きさでソートします。Apple 純正の Weather app はすでに両方を使用しています。Changes はホーム画面で「明日気温急降下」をハイライトし、Historical Comparisons は「今日の最高気温が歴史平均より 3°C 高い」を表示します。

この 2 つの新クエリに加え、予報データ自体も細かくなっています。current conditions と hourly forecast に高度別雲量(cloud cover by altitude)が追加され、hourly には時間ごとの降水量(precipitationAmount)が追加され、daily forecast は昼/夜に分割(day parts)でき、高低温湿度も返せます。Apple Weather app がずっと使ってきたデータで、サードパーティも取得できるようになりました。REST API には FlatBuffers バイナリ形式も追加され、圧縮 JSON と比べて最大 25% のサイズ削減、90% の解析時間短縮が可能です。

詳細

時間ごとの降水量

Swift 側では .hourly クエリを指定し、precipitationAmount プロパティにアクセスするだけです(02:40):

let hourlyPrecipitation = try await WeatherService()
    .weather(for: .newYork, including: .hourly)
    .map(\.precipitationAmount)

キーポイント:

  • WeatherService().weather(for:including:) は WeatherKit のメインクエリ入口で、including パラメータでデータセットを指定します
  • .hourly は時間ごとの予報を要求し、HourlyForecast 配列を返します
  • .map(\.precipitationAmount) は key path で各時間の降水量を直接抽出し、他フィールドをスキップします

REST 側の同等の呼び出し(03:25):

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

キーポイント:

  • dataSets=forecastHourly で時間ごとの予報を指定します
  • relativeHourlyStartrelativeHourlyEnd は相対時間で範囲を指定し、Apple Weather Service が渡したタイムゾーンに基づいて開始・終了時刻を計算します
  • 範囲未指定時はデフォルト 24 時間、最大 240 時間まで要求できます

Changes クエリ

今後の天気変化を取得します(06:05):

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
}

キーポイント:

  • .changes は新しいクエリタイプで、WeatherChanges オブジェクトを返します
  • 各 change には startDateendDate、変化タイプ(increasedecreasesteady など)が含まれます
  • 上記例は明日発生する低温変化をフィルタし、.decrease が含まれる場合はユーザーに通知します

REST 側は dataSets=weatherChanges だけで OK です(06:43)。返される各 change オブジェクトには startDateendDatetypehighTemperatureIncrease など)が含まれます。有意な変化がなくても結果は返され、typesteady になります。

Historical Comparisons クエリ

今日の天気を歴史的平均と比較します(08:17):

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
}

キーポイント:

  • .historicalComparisons は偏差の顕著さでソートされた比較リストを返します
  • .first で最も偏差が大きい項目を取得します
  • 各比較には currentValue(現在値)、baselineValue(歴史基準値)、deviationType(偏差レベル:withinNormalRange/higher/muchHigher/lower/muchLower)、baselineType(統計手法、現在は mean)が含まれます

Statistics API:歴史平均と日次サマリー

新しい Statistics API は 2 つのクエリを提供します。Historical Averages は 1970 年以降の長期平均を返します(月次の例、11:11):

let averagePrecipitation = try await WeatherService()
    .monthlyStatistics(
        for: .newYork,
        startMonth: 1,
        endMonth: 12,
        including: .precipitation
    )

let averagePrecipitationAmountsPerMonth = Dictionary(
    grouping: averagePrecipitation,
    by: \.month
)

キーポイント:

  • monthlyStatistics は月ごとの歴史平均を取得し、月番号は 1〜12 です
  • 月ごとにグループ化した結果は、Apple Weather app が各月の降水平均表示に使います

Daily Summary は過去任意の日の天気サマリーを返します(2021 年 8 月 1 日まで遡及可能、12:52):

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
}

キーポイント:

  • dailySummary は日付区間を受け取り、その範囲内の各日のサマリーを返します
  • サマリーには高低温、降水量、降雪量が含まれます
  • Apple Weather app はこれを過去 30 日の降水累積表示に使います

FlatBuffers バイナリ形式

REST API に FlatBuffers サポートが追加されました(14:16)。圧縮 JSON と比べ、サイズは最大 25% 削減、解析時間は最大 90% 短縮されます。Swift API は自動的にこの最適化の恩恵を受けます。REST 側はリクエストヘッダーの Accept で FlatBuffers を指定すれば有効化できます。

重要ポイント

  • 何を作るか:天気ホーム画面に「今後の変化」カードを追加します。Changes クエリを呼び、今後 24〜48 時間の気温・降水変化をフィルタし、.increase または .decrease を含む項目を目立つスタイルで表示します。なぜ価値があるか:ユーザーが天気 app を開くとき最も気になるのは「明日と今日の違い」で、このカードが直接答えます。どう始めるか.changes の返値には startDatetype が含まれるため、フロントエンドは単純なフィルタとレンダリングだけで済みます。

  • 何を作るか:当日の天気に「歴史同期比」ラベルを追加します。Historical Comparisons クエリを呼び、deviationTypewithinNormalRange でない項目を取り、「今日の最高気温が歴史平均より 3°C 高い」などの文言を表示します。なぜ価値があるか:28°C だけでは判断できません。「この月の平均は 22°C」と知って初めて意味が生まれます。どう始めるか.historicalComparisons の各オブジェクトには currentValuebaselineValue があり、減算で文言を生成できます。

  • 何を作るか:旅行計画ページに目的地の月別降水平均を表示します。Statistics API の monthlyStatistics で通年の降水データを要求し、棒グラフやカレンダーヒートマップで提示します。なぜ価値があるか:旅行計画では目的地の雨季/乾季を知る必要があり、純粋な予報データでは提供できません。どう始めるかmonthlyStatistics(for:startMonth:endMonth:including:) を 1 行呼び、月ごとにグループ化してチャートコンポーネントに渡します。

  • 何を作るか:REST API で FlatBuffers を採用し、転送と解析のオーバーヘッドを削減します。天気 app のバックエンドが WeatherKit REST API を頻繁に大量の履歴データ取得に使う場合、リクエストヘッダーに FlatBuffers の Accept を追加します。なぜ価値があるか:30 日分 daily summary など大量データでは 25% サイズ削減と 90% 高速解析が UX に直結します。どう始めるか:REST リクエストヘッダーで FlatBuffers 形式を指定。Swift API 側は変更不要です。

関連セッション

コメント

GitHub Issues · utterances