You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 01:47:51