weatherkit
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseWeatherKit
WeatherKit
Fetch current conditions, hourly and daily forecasts, weather alerts, and
historical statistics using . Display required Apple Weather
attribution. Targets Swift 6.2 / iOS 26+.
WeatherService使用获取当前天气状况、逐小时及每日预报、天气警报和历史统计数据。展示要求的Apple Weather版权声明。适配Swift 6.2 / iOS 26+。
WeatherServiceContents
目录
Setup
设置
Project Configuration
项目配置
- Enable the WeatherKit capability in Xcode (adds the entitlement)
- Enable WeatherKit for your App ID in the Apple Developer portal
- Add to Info.plist if using device location
NSLocationWhenInUseUsageDescription - WeatherKit requires an active Apple Developer Program membership
- 在Xcode中启用WeatherKit功能(会添加相关权限)
- 在Apple开发者后台为你的App ID启用WeatherKit
- 如果使用设备位置,在Info.plist中添加字段
NSLocationWhenInUseUsageDescription - WeatherKit要求拥有有效的Apple开发者计划会员资格
Import
导入
swift
import WeatherKit
import CoreLocationswift
import WeatherKit
import CoreLocationCreating the Service
创建服务实例
Use the shared singleton or create an instance. The service is and
thread-safe.
Sendableswift
let weatherService = WeatherService.shared
// or
let weatherService = WeatherService()使用共享单例或者创建新实例。该服务支持且线程安全。
Sendableswift
let weatherService = WeatherService.shared
// 或者
let weatherService = WeatherService()Fetching Current Weather
获取当前天气
Fetch current conditions for a location. Returns a object with all
available datasets.
Weatherswift
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())")
}获取指定位置的当前天气状况。返回包含所有可用数据集的对象。
Weatherswift
func fetchCurrentWeather(for location: CLLocation) async throws -> CurrentWeather {
let weather = try await weatherService.weather(for: location)
return weather.currentWeather
}
// 使用返回结果
func displayCurrent(_ current: CurrentWeather) {
let temp = current.temperature // Measurement<UnitTemperature>
let condition = current.condition // WeatherCondition枚举
let symbol = current.symbolName // SF Symbol名称
let humidity = current.humidity // Double类型(0-1)
let wind = current.wind // 风速、风向、阵风信息
let uvIndex = current.uvIndex // UVIndex
print("\(condition): \(temp.formatted())")
}Forecasts
天气预报
Hourly Forecast
逐小时预报
Returns 25 contiguous hours starting from the current hour by default.
swift
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)")
}默认返回从当前时间开始的连续25小时的预报。
swift
func fetchHourlyForecast(for location: CLLocation) async throws -> Forecast<HourWeather> {
let weather = try await weatherService.weather(for: location)
return weather.hourlyForecast
}
// 遍历逐小时预报
for hour in hourlyForecast {
print("\(hour.date): \(hour.temperature.formatted()), \(hour.condition)")
}Daily Forecast
每日预报
Returns 10 contiguous days starting from the current day by default.
swift
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)")
}默认返回从今日开始的连续10天的预报。
swift
func fetchDailyForecast(for location: CLLocation) async throws -> Forecast<DayWeather> {
let weather = try await weatherService.weather(for: location)
return weather.dailyForecast
}
// 遍历每日预报
for day in dailyForecast {
print("\(day.date): \(day.lowTemperature.formatted()) - \(day.highTemperature.formatted())")
print(" 天气状况: \(day.condition), 降水概率: \(day.precipitationChance)")
}Custom Date Range
自定义日期范围
Request forecasts for specific date ranges using .
WeatherQueryswift
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
}使用请求指定日期范围的预报。
WeatherQueryswift
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
}Weather Alerts
天气警报
Fetch active weather alerts for a location. Alerts include severity, summary,
and affected regions.
swift
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)")
if let detailsURL = alert.detailsURL {
// Link to full alert details
}
}
}获取指定位置的活跃天气警报。警报包含严重程度、摘要和受影响区域信息。
swift
func fetchAlerts(for location: CLLocation) async throws -> [WeatherAlert]? {
let weather = try await weatherService.weather(for: location)
return weather.weatherAlerts
}
// 处理警报
if let alerts = weatherAlerts {
for alert in alerts {
print("警报: \(alert.summary)")
print("严重程度: \(alert.severity)")
print("受影响区域: \(alert.region)")
if let detailsURL = alert.detailsURL {
// 跳转到完整警报详情页面
}
}
}Selective Queries
选择性查询
Fetch only the datasets you need to minimize API usage and response size. Each
type maps to one dataset.
WeatherQuery仅获取你需要的数据集,以减少API调用量和响应大小。每个类型对应一个数据集。
WeatherQuerySingle Dataset
单个数据集
swift
let current = try await weatherService.weather(
for: location,
including: .current
)
// current is CurrentWeatherswift
let current = try await weatherService.weather(
for: location,
including: .current
)
// current为CurrentWeather类型Multiple Datasets
多个数据集
swift
let (current, hourly, daily) = try await weatherService.weather(
for: location,
including: .current, .hourly, .daily
)
// current: CurrentWeather, hourly: Forecast<HourWeather>, daily: Forecast<DayWeather>swift
let (current, hourly, daily) = try await weatherService.weather(
for: location,
including: .current, .hourly, .daily
)
// current: CurrentWeather, hourly: Forecast<HourWeather>, daily: Forecast<DayWeather>Minute Forecast
分钟级预报
Available in limited regions. Returns precipitation forecasts at minute
granularity for the next hour.
swift
let minuteForecast = try await weatherService.weather(
for: location,
including: .minute
)
// minuteForecast: Forecast<MinuteWeather>? (nil if unavailable)仅在部分地区可用。返回未来一小时内分钟级的降水预报。
swift
let minuteForecast = try await weatherService.weather(
for: location,
including: .minute
)
// minuteForecast: Forecast<MinuteWeather>? (不可用时返回nil)Available Query Types
可用查询类型
| Query | Return Type | Description |
|---|---|---|
| | Current observed conditions |
| | 25 hours from current hour |
| | 10 days from today |
| | Next-hour precipitation (limited regions) |
| | Active weather alerts |
| | Dataset availability for location |
| 查询类型 | 返回类型 | 描述 |
|---|---|---|
| | 当前观测到的天气状况 |
| | 从当前时间开始的25小时预报 |
| | 从今日开始的10天预报 |
| | 未来一小时的分钟级降水预报(仅部分地区可用) |
| | 活跃天气警报 |
| | 指定位置的数据集可用性 |
Attribution
版权声明
Apple requires apps using WeatherKit to display attribution. This is a
legal requirement.
Apple要求使用WeatherKit的应用必须展示版权声明,这是一项法律要求。
Fetching Attribution
获取版权声明信息
swift
func fetchAttribution() async throws -> WeatherAttribution {
return try await weatherService.attribution
}swift
func fetchAttribution() async throws -> WeatherAttribution {
return try await weatherService.attribution
}Displaying Attribution in SwiftUI
在SwiftUI中展示版权声明
swift
import SwiftUI
import WeatherKit
struct WeatherAttributionView: View {
let attribution: WeatherAttribution
@Environment(\.colorScheme) private var colorScheme
var body: some View {
VStack(spacing: 8) {
// Display the Apple Weather mark
AsyncImage(url: markURL) { image in
image
.resizable()
.scaledToFit()
.frame(height: 20)
} placeholder: {
EmptyView()
}
// Link to the legal attribution page
Link("Weather data sources", destination: attribution.legalPageURL)
.font(.caption2)
.foregroundStyle(.secondary)
}
}
private var markURL: URL {
colorScheme == .dark
? attribution.combinedMarkDarkURL
: attribution.combinedMarkLightURL
}
}swift
import SwiftUI
import WeatherKit
struct WeatherAttributionView: View {
let attribution: WeatherAttribution
@Environment(\.colorScheme) private var colorScheme
var body: some View {
VStack(spacing: 8) {
// 展示Apple Weather标识
AsyncImage(url: markURL) { image in
image
.resizable()
.scaledToFit()
.frame(height: 20)
} placeholder: {
EmptyView()
}
// 链接到法律声明页面
Link("天气数据来源", destination: attribution.legalPageURL)
.font(.caption2)
.foregroundStyle(.secondary)
}
}
private var markURL: URL {
colorScheme == .dark
? attribution.combinedMarkDarkURL
: attribution.combinedMarkLightURL
}
}Attribution Properties
版权声明属性
| Property | Use |
|---|---|
| Apple Weather mark for light backgrounds |
| Apple Weather mark for dark backgrounds |
| Square Apple Weather logo |
| URL to the legal attribution web page |
| Text alternative when a web view is not feasible |
| Weather data provider name |
| 属性 | 用途 |
|---|---|
| 浅色背景下的Apple Weather标识 |
| 深色背景下的Apple Weather标识 |
| 方形Apple Weather图标 |
| 法律声明页面的链接 |
| 无法使用网页视图时的文本替代方案 |
| 天气数据提供商名称 |
Availability
可用性
Check which weather datasets are available for a given location. Not all datasets
are available in all countries.
swift
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
}
}检查指定位置支持哪些天气数据集。并非所有数据集在所有国家都可用。
swift
func checkAvailability(for location: CLLocation) async throws {
let availability = try await weatherService.weather(
for: location,
including: .availability
)
// 检查特定数据集的可用性
if availability.alertAvailability == .available {
// 可以安全获取警报
}
if availability.minuteAvailability == .available {
// 该地区支持分钟级预报
}
}Common Mistakes
常见错误
DON'T: Ship without Apple Weather attribution
错误做法:发布时未添加Apple Weather版权声明
Omitting attribution violates the WeatherKit terms of service and risks App Review
rejection.
swift
// WRONG: Show weather data without attribution
VStack {
Text("72F, Sunny")
}
// CORRECT: Always include attribution
VStack {
Text("72F, Sunny")
WeatherAttributionView(attribution: attribution)
}省略版权声明违反WeatherKit服务条款,可能导致应用审核被拒。
swift
// 错误示例:展示天气数据但未添加版权声明
VStack {
Text("72°F, 晴天")
}
// 正确示例:始终包含版权声明
VStack {
Text("72°F, 晴天")
WeatherAttributionView(attribution: attribution)
}DON'T: Fetch all datasets when you only need current conditions
错误做法:仅需当前状况时却获取所有数据集
Each dataset query counts against your API quota. Fetch only what you display.
swift
// WRONG: Fetches everything
let weather = try await weatherService.weather(for: location)
let temp = weather.currentWeather.temperature
// CORRECT: Fetch only current conditions
let current = try await weatherService.weather(
for: location,
including: .current
)
let temp = current.temperature每个数据集的查询都会计入API配额。仅获取你需要展示的数据。
swift
// 错误示例:获取所有数据
let weather = try await weatherService.weather(for: location)
let temp = weather.currentWeather.temperature
// 正确示例:仅获取当前天气状况
let current = try await weatherService.weather(
for: location,
including: .current
)
let temp = current.temperatureDON'T: Ignore minute forecast unavailability
错误做法:忽略分钟级预报不可用的情况
Minute forecasts return in unsupported regions. Force-unwrapping crashes.
nilswift
// WRONG: Force-unwrap minute forecast
let minutes = try await weatherService.weather(for: location, including: .minute)
for m in minutes! { ... } // Crash in unsupported regions
// CORRECT: Handle nil
if let minutes = try await weatherService.weather(for: location, including: .minute) {
for m in minutes { ... }
} else {
// Minute forecast not available for this region
}在不支持的地区,分钟级预报会返回nil。强制解包会导致崩溃。
swift
// 错误示例:强制解包分钟级预报
let minutes = try await weatherService.weather(for: location, including: .minute)
for m in minutes! { ... } // 在不支持的地区会崩溃
// 正确示例:处理nil情况
if let minutes = try await weatherService.weather(for: location, including: .minute) {
for m in minutes { ... }
} else {
// 该地区不支持分钟级预报
}DON'T: Forget the WeatherKit entitlement
错误做法:忘记添加WeatherKit权限
Without the capability enabled, calls throw at runtime.
WeatherServiceswift
// 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未启用该功能时,调用会在运行时抛出错误。
WeatherServiceswift
// 错误示例:未配置WeatherKit功能
let weather = try await weatherService.weather(for: location) // 抛出错误
// 正确示例:在Xcode的签名与功能中启用WeatherKit
// 并在Apple开发者后台为你的App ID启用该功能DON'T: Make repeated requests without caching
错误做法:不缓存数据,重复请求
Weather data updates every few minutes, not every second. Cache responses
to stay within API quotas and improve performance.
swift
// WRONG: Fetch on every view appearance
.task {
let weather = try? await fetchWeather()
}
// CORRECT: Cache with a staleness interval
actor WeatherCache {
private var cached: CurrentWeather?
private var lastFetch: Date?
func current(for location: CLLocation) async throws -> CurrentWeather {
if let cached, let lastFetch,
Date.now.timeIntervalSince(lastFetch) < 600 {
return cached
}
let fresh = try await WeatherService.shared.weather(
for: location, including: .current
)
cached = fresh
lastFetch = .now
return fresh
}
}天气数据每几分钟更新一次,并非每秒更新。缓存响应以避免超出API配额并提升性能。
swift
// 错误示例:每次视图出现时都获取数据
.task {
let weather = try? await fetchWeather()
}
// 正确示例:设置缓存过期时间
actor WeatherCache {
private var cached: CurrentWeather?
private var lastFetch: Date?
func current(for location: CLLocation) async throws -> CurrentWeather {
if let cached, let lastFetch,
Date.now.timeIntervalSince(lastFetch) < 600 {
return cached
}
let fresh = try await WeatherService.shared.weather(
for: location, including: .current
)
cached = fresh
lastFetch = .now
return fresh
}
}Review Checklist
审核检查清单
- WeatherKit capability enabled in Xcode and Apple Developer portal
- Active Apple Developer Program membership (required for WeatherKit)
- Apple Weather attribution displayed wherever weather data appears
- Attribution mark uses correct color scheme variant (light/dark)
- Legal attribution page linked or displayed
legalAttributionText - Only needed datasets fetched (not full
WeatherQuerywhen unnecessary)weather(for:) - Minute forecast handled as optional (nil in unsupported regions)
- Weather alerts checked for nil before iteration
- Responses cached with a reasonable staleness interval (5-15 minutes)
- checked before fetching region-limited datasets
WeatherAvailability - Location permission requested before passing to service
CLLocation - Temperature and measurements formatted with for locale
Measurement.formatted()
- 已在Xcode和Apple开发者后台启用WeatherKit功能
- 拥有有效的Apple开发者计划会员资格(WeatherKit必需)
- 所有展示天气数据的位置都添加了Apple Weather版权声明
- 版权声明标识使用了适配当前配色方案的版本(浅色/深色)
- 已链接到法律声明页面或展示了
legalAttributionText - 仅获取所需的数据集(无需时不调用完整的
WeatherQuery)weather(for:) - 已将分钟级预报作为可选类型处理(不支持地区返回nil)
- 遍历天气警报前已检查是否为nil
- 已为响应设置合理的缓存过期时间(5-15分钟)
- 获取地区受限的数据集前已检查
WeatherAvailability - 向服务传递前已请求位置权限
CLLocation - 温度和测量值已使用适配本地化
Measurement.formatted()
References
参考资料
- Extended patterns (SwiftUI dashboard, charts integration, historical statistics):
references/weatherkit-patterns.md - WeatherKit framework
- WeatherService
- WeatherAttribution
- WeatherQuery
- CurrentWeather
- Forecast
- HourWeather
- DayWeather
- WeatherAlert
- WeatherAvailability
- Fetching weather forecasts with WeatherKit
- 扩展模式(SwiftUI仪表盘、图表集成、历史统计数据):
references/weatherkit-patterns.md - WeatherKit框架
- WeatherService
- WeatherAttribution
- WeatherQuery
- CurrentWeather
- Forecast
- HourWeather
- DayWeather
- WeatherAlert
- WeatherAvailability
- 使用WeatherKit获取天气预报