Loading...
Loading...
Compare original and translation side by side
WeatherServiceWeatherServiceNSLocationWhenInUseUsageDescriptionNSLocationWhenInUseUsageDescriptionimport WeatherKit
import CoreLocationimport WeatherKit
import CoreLocationSendablelet weatherService = WeatherService.shared
// or
let weatherService = WeatherService()Sendablelet weatherService = WeatherService.shared
// 或者
let weatherService = WeatherService()Weatherfunc 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())")
}Weatherfunc 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())")
}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)")
}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)")
}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)")
}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)")
}WeatherQueryfunc 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
}WeatherQueryfunc 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 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
}
}
}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 {
// 跳转到完整警报详情页面
}
}
}WeatherQueryWeatherQuerylet current = try await weatherService.weather(
for: location,
including: .current
)
// current is CurrentWeatherlet current = try await weatherService.weather(
for: location,
including: .current
)
// current为CurrentWeather类型let (current, hourly, daily) = try await weatherService.weather(
for: location,
including: .current, .hourly, .daily
)
// current: CurrentWeather, hourly: Forecast<HourWeather>, daily: Forecast<DayWeather>let (current, hourly, daily) = try await weatherService.weather(
for: location,
including: .current, .hourly, .daily
)
// current: CurrentWeather, hourly: Forecast<HourWeather>, daily: Forecast<DayWeather>let minuteForecast = try await weatherService.weather(
for: location,
including: .minute
)
// minuteForecast: Forecast<MinuteWeather>? (nil if unavailable)let minuteForecast = try await weatherService.weather(
for: location,
including: .minute
)
// minuteForecast: Forecast<MinuteWeather>? (不可用时返回nil)| 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天预报 |
| | 未来一小时的分钟级降水预报(仅部分地区可用) |
| | 活跃天气警报 |
| | 指定位置的数据集可用性 |
func fetchAttribution() async throws -> WeatherAttribution {
return try await weatherService.attribution
}func fetchAttribution() async throws -> WeatherAttribution {
return try await weatherService.attribution
}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
}
}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
}
}| 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图标 |
| 法律声明页面的链接 |
| 无法使用网页视图时的文本替代方案 |
| 天气数据提供商名称 |
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
}
}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 {
// 该地区支持分钟级预报
}
}// WRONG: Show weather data without attribution
VStack {
Text("72F, Sunny")
}
// CORRECT: Always include attribution
VStack {
Text("72F, Sunny")
WeatherAttributionView(attribution: attribution)
}// 错误示例:展示天气数据但未添加版权声明
VStack {
Text("72°F, 晴天")
}
// 正确示例:始终包含版权声明
VStack {
Text("72°F, 晴天")
WeatherAttributionView(attribution: attribution)
}// 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// 错误示例:获取所有数据
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.temperaturenil// 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
}// 错误示例:强制解包分钟级预报
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 {
// 该地区不支持分钟级预报
}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 IDWeatherService// 错误示例:未配置WeatherKit功能
let weather = try await weatherService.weather(for: location) // 抛出错误
// 正确示例:在Xcode的签名与功能中启用WeatherKit
// 并在Apple开发者后台为你的App ID启用该功能// 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
}
}// 错误示例:每次视图出现时都获取数据
.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
}
}legalAttributionTextWeatherQueryweather(for:)WeatherAvailabilityCLLocationMeasurement.formatted()legalAttributionTextWeatherQueryweather(for:)WeatherAvailabilityCLLocationMeasurement.formatted()references/weatherkit-patterns.mdreferences/weatherkit-patterns.md