使用WeatherKit在SwiftUI中替换天气图标为表情符号遇阻求助
问题分析与解决方案
你的代码主要存在三个核心问题:
1. lookslikemoji属性未正确映射枚举
当前lookslikemoji只是把枚举类型转换成字符串(结果是"WeatherKitManager.WeatherEmoji"),完全没有根据WeatherKit返回的天气标识去匹配对应的枚举实例,自然拿不到表情符号。
2. 枚举关联值类型选择不当
emojiweather返回LocalizedStringKey毫无必要,表情符号不需要本地化处理,直接返回String类型更简洁实用。
3. 未覆盖WeatherKit的昼夜标识
WeatherKit返回的symbolName会包含昼夜后缀(比如clearNight),你的枚举里没有覆盖这类情况,导致部分场景无法匹配表情。
修正后的完整代码
import Foundation import WeatherKit import SwiftUI @MainActor class WeatherKitManager: ObservableObject { @Published var weather: Weather? func getWeather() async { do { weather = try await Task.detached(priority: .userInitiated) { return try await WeatherService.shared.weather(for: .init(latitude: 42.28851, longitude: 13.55401)) }.value } catch { fatalError("\(error)") } } enum WeatherEmoji: String { case blowingDust, clear, cloudy, foggy, haze, mostlyClear, mostlyCloudy case partlyCloudy, smokey, breezy, windy, drizzle, heavyRain, isolatedThunderstorms case rain, sunShowers, scatteredThunderstorms, strongStorms, thunderstorms case frigid, hail, hot, flurries, sleet, snow, sunFlurries, wintryMix case blizzard, blowingSnow, freezingDrizzle, freezingRain, heavySnow case hurricane, tropicalStorm // 补充夜间天气标识 case clearNight, mostlyClearNight, partlyCloudyNight var emoji: String { switch self { case .clear, .clearNight: return self == .clearNight ? "🌙" : "☀️" case .blowingDust: return "💨" case .cloudy: return "☁️" case .foggy: return "🌫️" case .haze, .smokey: return "😶🌫️" case .mostlyClear, .mostlyClearNight: return self == .mostlyClearNight ? "🌙☁️" : "🌤️" case .mostlyCloudy: return "🌥️" case .partlyCloudy, .partlyCloudyNight: return self == .partlyCloudyNight ? "⛅️🌙" : "⛅️" case .breezy, .flurries: return "💨" case .windy: return "🍃" case .drizzle: return "☔️" case .heavyRain, .rain, .freezingRain: return "🌧️" case .isolatedThunderstorms, .scatteredThunderstorms: return "⚡️" case .strongStorms, .thunderstorms: return "⛈️" case .frigid, .wintryMix: return "🧣" case .hail: return "❄️" case .hot: return "🔥" case .sleet, .blizzard, .blowingSnow, .heavySnow: return "🌨️" case .snow: return "☃️" case .sunShowers, .sunFlurries: return "🌤️" case .freezingDrizzle: return "🥶" case .hurricane, .tropicalStorm: return "🌪️" } } } // 正确获取表情的属性 var weatherEmoji: String { guard let symbolName = weather?.currentWeather.symbolName else { return "❓" } // 先尝试完整匹配,失败则移除Night后缀兼容昼夜场景 if let emojiCase = WeatherEmoji(rawValue: symbolName) { return emojiCase.emoji } else { let dayVersion = symbolName.replacingOccurrences(of: "Night", with: "") return WeatherEmoji(rawValue: dayVersion)?.emoji ?? "❓" } } var symbol: String { weather?.currentWeather.symbolName ?? "xmark" } var temp: String { guard let temp = weather?.currentWeather.temperature else { return "Loading Weather Data" } return temp.converted(to: .celsius).formatted( .measurement(width: .narrow, usage: .asProvided, numberFormatStyle: .number.precision(.fractionLength(0))) ) } var feelslike: String { guard let feelslike = weather?.currentWeather.apparentTemperature else { return "Loading Weather Data" } return feelslike.converted(to: .celsius).formatted( .measurement(width: .narrow, usage: .asProvided, numberFormatStyle: .number.precision(.fractionLength(0))) ) } }
关键修正说明
- 将枚举的
emojiweather改为emoji,返回类型调整为String,去掉不必要的本地化类型。 - 补充夜间天气标识的枚举项,并在表情映射中区分昼夜显示。
- 新增
weatherEmoji属性:优先用完整标识匹配枚举,失败则兼容移除昼夜后缀的场景,确保大部分天气类型都能匹配到对应表情。 - 优化温度相关属性的写法,用
guard let替代可选链,代码逻辑更清晰。
内容的提问来源于stack exchange,提问作者helloimbrando
相关产品推荐
相关产品推荐

