SwiftUI结合Combine调用OpenWeather无返回且报初始化不匹配错误
问题根因
- 接口返回格式匹配错误:OpenWeather对应接口返回的是单个JSON对象,你当前设置的解码类型为
[WeatherDataModel].self(对象数组),类型不匹配直接导致解码失败,由于你没有捕获错误所以看不到具体报错。 - 命名冲突导致初始化报错:你定义了全局
typealias weatherData = [WeatherDataModel],又在View中用@StateObject var weatherData = DownloadWeatherData(),变量名和类型别名重名,编译器无法识别类型,就会报No exact matches in call to initializer错误。
修复方案
1. 修正网络请求类的解码逻辑和属性类型
OpenWeather返回的是单个天气对象,不需要用数组接收,同时添加错误打印方便调试:
class DownloadWeatherData: ObservableObject { // 改成可选单个对象,不要数组 @Published var weatherdata: WeatherDataModel? var weatherCancellabes = Set<AnyCancellable>() init() { print("loading weather init") getWeather(weatherUrl: "<my url>") } func getWeather(weatherUrl: String) { guard let weatherUrl = URL(string: weatherUrl) else { return } URLSession.shared.dataTaskPublisher(for: weatherUrl) .subscribe(on: DispatchQueue.global(qos: .background)) .receive(on: DispatchQueue.main) .tryMap { (data, response) -> Data in guard let response = response as? HTTPURLResponse, response.statusCode >= 200 && response.statusCode < 300 else { throw URLError(.badServerResponse) } // 可选:打印返回的JSON字符串方便排查字段问题 if let jsonStr = String(data: data, encoding: .utf8) { print("返回JSON:\n\(jsonStr)") } return data } // 解码类型改为单个WeatherDataModel,不是数组 .decode(type: WeatherDataModel.self, decoder: JSONDecoder()) .sink { completion in // 添加错误捕获,解码失败会直接打印原因 if case .failure(let error) = completion { print("请求/解码失败: \(error)") } } receiveValue: { [weak self] returnedWeatherData in self?.weatherdata = returnedWeatherData print("解码成功: \(returnedWeatherData)") } .store(in: &weatherCancellabes) } }
2. 修正View层的命名和渲染逻辑
修改变量名避免和全局typealias冲突,适配单个对象的渲染逻辑:
struct WeatherView: View { // 变量名改个不冲突的,比如weatherVM @StateObject var weatherVM = DownloadWeatherData() var body: some View { VStack { if let weather = weatherVM.weatherdata { Text("时区:\(weather.timezone)") Text("当前温度:\(weather.current.temp)") // 遍历daily字段显示每日天气 ForEach(weather.daily, id: \.dt) { day in Text("日期时间戳:\(day.dt) 最高温:\(day.temp.max)") } } else { Text("天气数据加载中...") } } } }
内容的提问来源于stack exchange,提问作者Robert
相关产品推荐
相关产品推荐

