SwiftUI - 无法呈现 jsonData
Posted
技术标签:
【中文标题】SwiftUI - 无法呈现 jsonData【英文标题】:SwiftUI - Not able to render the jsonData 【发布时间】:2020-05-05 06:33:55 【问题描述】:我对 SwiftUi 非常陌生,我正在尝试查看 json 数据,我目前正在从 openweathermap.org 检索天气数据,这是一个用于检索当前天气的免费 API。我收到解析天气 Json 消息时出错。我不确定我做错了什么!任何帮助将不胜感激,我已经坚持了一天。我参考了许多关于如何使用 Published var 和 ObservableObject 的博客和教程,但我无法解决这个问题。
This is my swift file
struct WeatherData
public var Id: Int
public var main: String
public var weather: [Weather]
public var icon: String
extension WeatherData: Decodable, Identifiable
var id: Int return Id
struct WeatherView: View
@ObservedObject var fetch = FetchWeather()
var body: some View
VStack
List(fetch.weatherData)
wthr in
VStack(alignment: .leading)
Text("\(wthr.id)")
Text("\(wthr.weather[0].description)")
Text("\(wthr.icon)")
.font(.system(size:11))
.foregroundColor(Color.gray)
struct Weather: Decodable
let description: String
struct WeatherView_Previews: PreviewProvider
static var previews: some View
WeatherView()
class FetchWeather: ObservableObject
@Published var weatherData = [WeatherData] ()
init()
load()
func load()
let url = URL(string: "https://api.openweathermap.org/data/2.5/weather?q=London&appid=myapikey")!
URLSession.shared.dataTask(with: url)
(data, response, error) in
do
if let wthData = data
let decodedData = try JSONDecoder().decode([WeatherData].self, from: wthData)
DispatchQueue.main.sync
self.weatherData = decodedData
else
print("No json Data available")
catch
print("Error parsing Weather Json")
.resume()
【问题讨论】:
很可能你的结构是错误的,但你没有打印相关的错误,而是一些硬编码的字符串,这真的很糟糕。将 catch 中的 print 语句更改为print(error)
。然后你可以谷歌或在 *** 上搜索更多信息,因为这个 api 似乎很受欢迎。 *** search
请阅读 JSON。根对象显然不是一个数组。并且永远不要在主线程上.sync
你遇到了什么错误?
@jawadAli 错误很明显:Expected array but found dictionary
@JoakimDanielson 非常感谢您的回复。我更改为错误并收到此消息: typeMismatch(Swift.Array, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Array but found a dictionary instead.", 基础错误:无))
【参考方案1】:
试试这个代码。我已注册获取 api 并相应地更正了模型、视图模型和视图。我还没有为图标字符串添加图像加载器。
import SwiftUI
struct Weather: Decodable
var description: String
var icon :String
struct MainData: Decodable
var temp: Double
var pressure: Int
var humidity: Int
var temp_min: Double
var temp_max: Double
struct WeatherData: Decodable, Identifiable
var id: Int
var main: MainData
var weather: [Weather]
var name: String
struct WeatherView: View
@ObservedObject var fetch = FetchWeather()
var body: some View
VStack(alignment: .leading)
Text("Current Weather").font(.title).padding()
List(fetch.weatherData) wthr in
HStack
VStack(alignment: .leading)
Text("\(wthr.name)")
Text("\(wthr.weather[0].description)")
.font(.system(size:11))
.foregroundColor(Color.gray)
Spacer()
VStack(alignment: .trailing)
Text("\(wthr.main.temp-273.15, specifier: "%.1f") ºC")
Text("\(wthr.weather[0].icon)") // Image from "https://openweathermap.org/img/w/\(wthr.weather[0].icon).png"
.foregroundColor(Color.gray)
class FetchWeather: ObservableObject
@Published var weatherData = [WeatherData]()
private let baseURL = "https://api.openweathermap.org/data/2.5/weather?q="
private let cities = [ "London", "Mumbai", "New+york", "Vatican+City" ]
private let api = "&appid="+"e44ebeb18c332fff46ab956bb38f9e07"
init()
for city in self.cities
self.load(self.baseURL+city+self.api)
func load(_ urlString: String)
if let url = URL(string: urlString)
URLSession.shared.dataTask(with: url) (data, response, error) in
do
if let wthData = data
let decodedData = try JSONDecoder().decode(WeatherData.self, from: wthData)
DispatchQueue.main.sync
self.weatherData.append(decodedData)
else
print("No json Data available")
catch let error as NSError
print(error.localizedDescription)
.resume()
else
print("Unable to decode URL")
【讨论】:
@amithrampur 代码中的api是有限使用的。使用您自己的 API。此外,如果这有效,请接受答案。干杯! 是的,这段代码很好,我会努力改进我的应用程序。非常感谢您回来查看 我确实有一个问题。如果我不想为城市设置值,我想直接从用户那里读取它怎么办。 @AmithRampur 在实际用例场景中,如果用户提供一些数据,则需要将其存储在 CoreData 或 Google Firebase 等永久存储中。对于核心数据集成,请查看github.com/nikhiljohn10/CoreData-MacOS。 我希望通过文本从用户那里获取输入,并在不同的视图中使用相同的输入。例如,上面天气 api 结构中的名称可以说有一个文本框供用户输入城市名称,用户输入圣何塞,我想根据用户输入的输入检索天气。我想知道我怎么能做到这一点。任何的意见都将会有帮助。我不想存储在永久存储中以上是关于SwiftUI - 无法呈现 jsonData的主要内容,如果未能解决你的问题,请参考以下文章
我无法获取用户的 AWS Cognito 凭证 (swiftUI)
在 Xcode 11、SwiftUI 中呈现 UIViewController 的问题
从 SwiftUI 视图呈现 UIActivityViewController