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

SwiftUI报错:init(_:)要求OneCall.HourlyResponse遵循StringProtocol

报错根因
  • 触发编译报错的直接原因:SwiftUI的Text组件初始化要求传入值符合StringProtocol(即字符串类型),但你传入的weather.hourly是自定义的OneCall.HourlyResponse结构体类型,系统无法自动将结构体转换为字符串,因此抛出类型不匹配错误。
  • 底层逻辑问题:你的数据模型定义和OpenWeatherMap OneCall API 1.0的实际返回结构完全不符:接口返回的hourly字段是逐小时天气数据的数组,不是单个自定义对象;同时你定义的HourlyResponse内部字段也和接口返回字段不匹配,即使绕过当前编译报错,后续接口数据解码也会失败。
修复方案

1. 修正数据模型定义

按照OpenWeatherMap接口的实际返回结构调整模型,注意hourly是数组类型,单条逐小时数据定义为可识别结构,方便ForEach遍历:

struct OneCall: Decodable{
    let lat, lon: Double
    let timezone : String
    let timezone_offset : Int
    let current: CurrentResponse
    // hourly为逐小时数据数组,接口默认返回48条数据
    let hourly: [HourlyEntry]

    // 单条逐小时数据结构,遵循Identifiable方便列表遍历
    struct HourlyEntry: Decodable, Identifiable {
        // 本地使用的唯一ID,不参与接口解码
        let id = UUID()
        // 接口返回的时间戳
        let dt: TimeInterval
        // 对应小时的温度
        let temp: Double
        // 天气状况数组
        let weather: [WeatherMeta]
        // 如需用到降水概率pop、体感温度feels_like等字段,可对照接口文档自行补充
    }

    struct WeatherMeta: Decodable {
        let main: String
        let description: String
        let icon: String
    }

    // 其余原有子结构体(如CurrentResponse)保持原有定义即可
}

2. 修正视图层遍历逻辑

不要写死遍历区间,直接遍历解码后的逐小时数据数组,传入Text的必须是明确的字符串值:

ScrollView(.horizontal){
    HStack(spacing: 12) {
        // 取前25条逐小时数据遍历
        ForEach(Array(weather.hourly.prefix(25))) { hourItem in
            VStack(spacing: 8){
                // 示例:显示格式化后的小时时间
                Text(formatTimestampToHour(hourItem.dt))
                    .font(.caption)
                // 示例:显示整数温度,拼接摄氏度符号
                Text("\(Int(hourItem.temp))°")
                    .bold()
                    .font(.subheadline)
            }
            .frame(width: 60)
        }
    }
}

// 时间戳转小时字符串的辅助方法
func formatTimestampToHour(_ timestamp: TimeInterval) -> String {
    let date = Date(timeIntervalSince1970: timestamp)
    let formatter = DateFormatter()
    formatter.dateFormat = "HH:mm"
    return formatter.string(from: date)
}

临时绕过方案:如果只是想快速消除当前编译报错不考虑解码逻辑,可以把Text(weather.hourly)改成Text(weather.hourly.hourly),直接传入结构体内部的字符串属性,但这种方式不符合接口实际结构,无法正常解析接口返回数据,仅做临时测试用。

内容的提问来源于stack exchange,提问作者Aadish123

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 03:16:06