weatherkit について
weatherkitは、WeatherServiceで気象データを取得するためのSwift開発者向けガイドです。選択的なクエリ、データの利用可否、応答のキャッシュ、Appleの帰属表示を扱います。
主な機能
- 01現在の天気と予報の取得
- 02警報と過去データとの比較
- 03WeatherQueryによるデータセット選択
- 04分単位予報と警報の利用可否確認
- 05帰属表示と応答キャッシュの処理
活用シーン
- 01アプリへの現在の天気表示の追加
- 02時間別・日別予報画面の構築
- 03地点の気象警報の表示
- 04天気と過去の平均値との比較
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ dpearson2699/ swift-ios-skills --skill weatherkitインストール後、Claude Code で/weatherkitを入力して読み込まれたか確認します。
同梱ファイルevals/evals.jsonreferences/weatherkit-patterns.md
詳細
WeatherKit
WeatherServiceを使用して、現在の気象状況、時間別および日別の予報、気象警報、過去の統計情報を取得します。必要なApple Weatherの帰属表示を行ってください。
目次
セットアップ
プロジェクトの設定
- XcodeでWeatherKit機能を有効にします(エンタイトルメントが追加されます)
- Apple DeveloperポータルでApp IDのWeatherKitを有効にします
- デバイスの位置情報を使用する場合は、Info.plistに
NSLocationWhenInUseUsageDescriptionを追加します - WeatherKitの利用には、有効なApple Developer Programメンバーシップが必要です
インポート
import WeatherKit
import CoreLocation
サービスの作成
共有シングルトンを使用するか、インスタンスを作成します。WeatherServiceはSendableに準拠しています。アプリのキャッシュとUIの状態は別々に分離して管理してください。
let weatherService = WeatherService.shared
// or
let weatherService = WeatherService()
現在の気象情報の取得
指定した場所の現在の気象状況を取得します。利用可能なすべてのデータセットを含むWeatherオブジェクトを返します。
WeatherKitの気温はMeasurement<UnitTemperature>値です。.formatted()を使って表示すると、単位と数値の形式がユーザーのロケールに従います。
func fetchCurrentWeather(for location: CLLocation) async throws -> CurrentWeather {
let weather = try await weatherService.weather(for: location)
return weather.currentWeather
}
// Using the result
func displayCurrent(_ current: CurrentWeather) {
let temp = current.temperature // Measurement<UnitTemperature>
let condition = current.condition // WeatherCondition enum
let symbol = current.symbolName // SF Symbol name
let humidity = current.humidity // Double (0-1)
let wind = current.wind // Wind (speed, direction, gust)
let uvIndex = current.uvIndex // UVIndex
print("\(condition): \(temp.formatted())")
}
予報
時間別予報
デフォルトでは、現在の時刻から始まる連続した25時間分を返します。
func fetchHourlyForecast(for location: CLLocation) async throws -> Forecast<HourWeather> {
let weather = try await weatherService.weather(for: location)
return weather.hourlyForecast
}
// Iterate hours
for hour in hourlyForecast {
print("\(hour.date): \(hour.temperature.formatted()), \(hour.condition)")
}
日別予報
デフォルトでは、現在の日から始まる連続した10日分を返します。
func fetchDailyForecast(for location: CLLocation) async throws -> Forecast<DayWeather> {
let weather = try await weatherService.weather(for: location)
return weather.dailyForecast
}
// Iterate days
for day in dailyForecast {
print("\(day.date): \(day.lowTemperature.formatted()) - \(day.highTemperature.formatted())")
print(" Condition: \(day.condition), Precipitation: \(day.precipitationChance)")
}
カスタムの日付範囲
WeatherQueryを使って、特定の日付範囲の予報をリクエストします。
日別および時間別の日付範囲クエリでは、startDateの日付は含まれ、endDateの日付は含まれません。2021年8月1日以降の過去のデータも含めることができます。予報は最大で10日先まで利用でき、1回のリクエストで返されるのは、日別予報で最大10日分、時間別予報で約240時間分です。
func fetchExtendedForecast(for location: CLLocation) async throws -> Forecast<DayWeather> {
let startDate = Date.now
let endDate = Calendar.current.date(byAdding: .day, value: 10, to: startDate)!
let forecast = try await weatherService.weather(
for: location,
including: .daily(startDate: startDate, endDate: endDate)
)
return forecast
}
明日の天気に関する案内が必要な場合は、分単位の予報ではなく、現地時間の明日の日付範囲をリクエストします。
func fetchTomorrowForecast(for location: CLLocation) async throws -> Forecast<DayWeather> {
let calendar = Calendar.current
let tomorrow = calendar.startOfDay(
for: calendar.date(byAdding: .day, value: 1, to: .now)!
)
let dayAfterTomorrow = calendar.date(byAdding: .day, value: 1, to: tomorrow)!
return try await weatherService.weather(
for: location,
including: .daily(startDate: tomorrow, endDate: dayAfterTomorrow)
)
}
気象警報
指定した場所の有効な気象警報を取得します。警報には、重大度、概要、対象地域が含まれます。
func fetchAlerts(for location: CLLocation) async throws -> [WeatherAlert]? {
let weather = try await weatherService.weather(for: location)
return weather.weatherAlerts
}
// Process alerts
if let alerts = weatherAlerts {
for alert in alerts {
print("Alert: \(alert.summary)")
print("Severity: \(alert.severity)")
print("Region: \(alert.region ?? "Unknown region")")
print("Details: \(alert.detailsURL)") // Non-optional and required for attribution
}
}
警報ダッシュボードで対応状況の確認について説明する場合は、WeatherAvailabilityを明示してください。公開されるのはalertAvailabilityとminuteAvailabilityのみであり、現在、時間別、日別の天気に関する包括的な利用可能状況の一覧ではありません。
選択的なクエリ
APIの使用量とレスポンスのサイズを最小限に抑えるため、必要なデータセットのみを取得します。各WeatherQuery型は1つのデータセットに対応します。
単一のデータセット
let current = try await weatherService.weather(
for: location,
including: .current
)
// current is CurrentWeather
複数のデータセット
let (current, hourly, daily) = try await weatherService.weather(
for: location,
including: .current, .hourly, .daily
)
// current: CurrentWeather, hourly: Forecast<HourWeather>, daily: Forecast<DayWeather>
分単位の予報
一部の地域でのみ利用できます。今後1時間の降水予報を分単位で返します。
let minuteForecast = try await weatherService.weather(
for: location,
including: .minute
)
// minuteForecast: Forecast<MinuteWeather>? (nil if unavailable)
利用可能なクエリの種類
| クエリ | 戻り値の型 | 説明 |
|---|---|---|
.current | CurrentWeather | 現在観測されている気象状況 |
.hourly | Forecast<HourWeather> | 現在の時刻から25時間分 |
.daily | Forecast<DayWeather> | 今日から10日分 |
.minute | Forecast<MinuteWeather>? | 今後1時間の降水予報(一部地域のみ) |
.alerts | [WeatherAlert]? | 有効な気象警報 |
.availability | WeatherAvailability | 警報および分単位の予報の利用可能状況のみ |
.changes | WeatherChanges? | 近いうちに予想される重要な気象変化(iOS 18以降) |
.historicalComparisons | HistoricalComparisons? | 現在の気象状況と過去の平均値との比較(iOS 18以降) |
コンテキストクエリ
iOS 18 以降で「明日の変わった天気」や「何が変わる?」機能を実装する場合は、オプションの .changes と .historicalComparisons の結果を一緒にリクエストしてください。前者は今後の重要な変化を報告し、後者は過去の状況を提供します。
let (changes, comparisons) = try await weatherService.weather(
for: location,
including: .changes, .historicalComparisons
)
過去の概要と統計には、WeatherQuery ではなく WeatherService のメソッドを使用します。タプルの順序、API、統計固有のプロパティについては、references/weatherkit-patterns.md を読み込んでください。
クレジット表記
Apple は、WeatherKit を使用するアプリにクレジット表記の表示を義務付けています。これは法的要件です。
クレジット表記の取得
func fetchAttribution() async throws -> WeatherAttribution {
return try await weatherService.attribution
}
SwiftUI のクレジット表記ビューとキャッシュとの統合については、references/weatherkit-patterns.md を読み込んでください。
クレジット表記のプロパティ
| プロパティ | 用途 |
|---|---|
combinedMarkLightURL | 明るい背景向けの Apple Weather マーク |
combinedMarkDarkURL | 暗い背景向けの Apple Weather マーク |
squareMarkURL | 正方形の Apple Weather ロゴ |
legalPageURL | 法的なクレジット表記を掲載したウェブページの URL |
legalAttributionText | ウェブビューを使用できない場合の代替テキスト |
serviceName | 気象データプロバイダー名 |
利用可能状況
ある場所で気象警報または分単位の予報を利用できるか確認します。WeatherAvailability が報告するのは、警報と分単位の予報の利用可否のみです。現在の天気など、ほかのデータセットは、地理上の場所でサポートされることが想定されています。
func checkAvailability(for location: CLLocation) async throws {
let availability = try await weatherService.weather(
for: location,
including: .availability
)
// Check specific dataset availability
if availability.alertAvailability == .available {
// Safe to fetch alerts
}
if availability.minuteAvailability == .available {
// Minute forecast available for this region
}
}
よくある間違い
してはいけないこと:Apple Weather のクレジット表記を表示せずにリリースする
WeatherKit のデータを表示するすべての場所で、適切な Apple Weather マークを表示し、legalPageURL へのリンクを設定してください。legalAttributionText を使うのは、法的なページを表示できない場合に限ります。
してはいけないこと:現在の状況だけが必要なのに、すべてのデータセットを取得する
データセットのクエリはそれぞれ API クォータにカウントされます。選択的なクエリに示すクエリを使い、UI に表示するデータだけを取得してください。
してはいけないこと:分単位の予報が利用できない場合を無視する
分単位の予報は、サポート対象外の地域では利用できないことがあります。利用可否を確認し、強制アンラップするのではなく、nil の結果を処理してください。
してはいけないこと:WeatherKit のエンタイトルメントを設定し忘れる
この機能を有効にしないと、WeatherService の呼び出しは実行時にエラーをスローします。
// WRONG: No WeatherKit capability configured
let weather = try await weatherService.weather(for: location) // Throws
// CORRECT: Enable WeatherKit in Xcode Signing & Capabilities
// and in the Apple Developer portal for your App ID
してはいけないこと:キャッシュせずにリクエストを繰り返す
WeatherKit のモデルには metadata.expirationDate が含まれています。固定の間隔を独自に設定したり、ビューが表示されるたびに取得したりせず、有効期限までレスポンスをキャッシュしてください。loadIfNeeded の管理はモデルまたはキャッシュに任せてください。完全なアクターパターンについては、references/weatherkit-patterns.md をご覧ください。
レビューチェックリスト
- Xcode と Apple Developer ポータルで WeatherKit の機能が有効になっている
- 有効な Apple Developer Program のメンバーシップがある(WeatherKit に必要)
- 気象データを表示するすべての場所で Apple Weather のクレジット表記を表示している
- クレジット表記のマークに適切な配色のバリエーション(明るい/暗い)を使っている
- 法的なクレジット表記のページにリンクするか、
legalAttributionTextを表示している - 必要な
WeatherQueryのデータセットだけを取得している(不要な場合にweather(for:)ですべて取得していない) - 分単位の予報をオプションとして処理している(サポート対象外の地域では nil)
- 気象警報を反復処理する前に nil かどうか確認している
- 警報の詳細リンクにはオプションではない
detailsURLを使い、オプションのregionは nil を安全に処理している - 各モデルの
metadata.expirationDateまでレスポンスをキャッシュしている -
WeatherAvailabilityを警報/分単位の予報の利用可否の確認に使用し、広範なサポート状況の一覧として扱っていない -
CLLocationをサービスに渡す前に位置情報の許可を求めている - 地域に応じて、
Measurement.formatted()で気温と計測値をフォーマットしている
参考資料
- 拡張パターン(SwiftUI ダッシュボード、グラフとの統合、過去の統計情報):references/weatherkit-patterns.md
- WeatherKit フレームワーク
- WeatherService
- WeatherAttribution
- WeatherQuery
- WeatherQuery.daily(startDate:endDate:)
- WeatherQuery.hourly(startDate:endDate:)
- CurrentWeather
- CurrentWeather.temperature
- Measurement.formatted()
- Forecast
- HourWeather
- DayWeather
- WeatherAlert
- WeatherAvailability
- WeatherMetadata.expirationDate
- WeatherQuery.changes
- WeatherQuery.historicalComparisons
- WeatherKit の更新情報
- 今日の天気に背景情報を加える
- WeatherKit で天気予報を取得する