Swift调用OpenWeatherMap逐小时预报出现初始化器无精确匹配错误
问题描述
开发iOS天气应用对接OpenWeatherMap API获取逐小时预报数据时,尝试在SwiftUI的Text组件中展示预报内容,触发报错:No exact matches in call to initializer,逐小时天气预报模块无法正常渲染。
涉及代码如下:
页面布局代码
ScrollView(.horizontal){ HStack(spacing: 5.0) { ForEach(0..<25) {_ in VStack{ Text([weather.hourly.hourly]) // 报错触发位置 .bold() .font(.subheadline) .frame(width: 105, height: 15) } } } }
接口数据模型代码
struct OneCall: Decodable { let lat, lon: Double let timezone : String let timezone_offset : Int let current: CurrentResponse let hourly: HourlyResponse struct HourlyResponse: Decodable{ let sunrise: Date? let sunset: Date? var hourly: Array<CurrentResponse> } }
报错根因
Text组件入参类型不匹配:SwiftUI的Text初始化器仅支持String、LocalizedStringKey等合法文本类型入参,代码中传入的[weather.hourly.hourly]是将数组二次包裹生成的二维数组,无对应可用的初始化方法,直接触发报错。- 遍历逻辑失效:
ForEach(0..<25)循环过程中未使用索引读取对应位置的单条预报数据,直接传入全量数组无法渲染单小时预报条目。 - 数据模型层级错误:OpenWeatherMap OneCall接口的
hourly字段本身就是逐小时预报对象数组,现有模型额外嵌套HourlyResponse结构体、多定义了一层hourly属性,会导致JSON解码失败,无法拿到正确的逐小时数据。
修复方案
1. 对齐接口结构修正数据模型
移除多余的嵌套层级,修正后的数据模型如下:
struct OneCall: Decodable { let lat, lon: Double let timezone : String let timezone_offset : Int let current: CurrentResponse // 移除多余的HourlyResponse嵌套,hourly直接为逐小时预报数组 let hourly: [CurrentResponse] }
注意:需保证
CurrentResponse结构体遵循Decodable协议,且字段名、字段类型与接口返回结构完全匹配,避免解码失败。
2. 修正页面遍历渲染逻辑
直接遍历逐小时数组的前25项,取出单条预报的对应字段转为字符串后传入Text组件,修正后布局代码如下:
ScrollView(.horizontal){ HStack(spacing: 5.0) { // 取数组前25项遍历,以预报的时间戳dt作为唯一标识 ForEach(Array(weather.hourly.prefix(25)), id: \.dt) { hourForecast in VStack{ // 按需替换为要展示的预报字段,转为字符串传入Text,示例为展示温度 Text("\(hourForecast.temp, specifier: "%.0f")°") .bold() .font(.subheadline) .frame(width: 105, height: 15) } } } }
如果需要展示预报时间,提前配置DateFormatter将返回的时间戳转换为目标格式的字符串,再传入Text组件即可。
内容的提问来源于stack exchange,提问作者Aadish123
相关产品推荐
相关产品推荐

