"Out of index" SwiftUI ContentView 中的错误但不在函数中
"Out of index" error within SwiftUI ContentView but not in function
我正在创建一个天气应用程序。我使用 API (OpenWeatherApp) 来获取我的数据。我将数据加载到类型为 struct WeatherJSON
.
的数组 weatherArray
中
我可以使用 ForEach
循环成功访问数据,但是当我尝试使用 array[index]
直接访问特定数据时,出现以下错误:Thread 1: Fatal error: Index out of range
这是我正在使用的顶级结构:
// holds all data from the JSON request
struct WeatherJSON: Codable {
var coord: Coord // coordinate struct
var weather: [Weather] // array of Weather struct
var base: String // "internal parameter..?"
var main: Main // main struct (contains the juicy data)
var visibility: Int // visibility number
var wind: Wind // wind struct
var clouds: Clouds // clouds struct
var dt: Int // time of data calculation, unix, UTC
var sys: Sys // internal parameer
var timezone, id: Int // timezone
var name: String // city namme
var cod: Int // another internal parameter (..?)
}
我的内容视图:
struct ContentView: View {
@State private var weatherArray: [WeatherJSON] = []
// @State private var weatherArray: [Weather] = []
var body: some View {
NavigationView {
VStack {
Text("\(weatherArray[0].name)") // <---- This doesn't work
List {
// Text("Current conditions: \(weatherArray[0].description)")
// ForEach(weatherArray, id: \.self) { result in
// Section(header:Text("Address")) {
// Text("Current conditions: \(result.main)")
// .font(.headline)
// .bold()
// Text("Weather description: \(result.description)")
// .font(.body)
// }
// }
}
.navigationTitle("Weather")
}
}
.task { await handleData() }
}
func handleData() async {
guard let url = URL(string: "https://api.openweathermap.org/data/2.5/weather?q=Seattle&appid={APIKEY}") else {
print("This URL does not work!")
return
}
let decoder = JSONDecoder()
do {
let (weatherData, _) = try await URLSession.shared.data(from: url)
if let weatherObj = try? decoder.decode(WeatherJSON.self, from: weatherData) {
weatherArray.append(weatherObj)// = weatherObj.weather
print(weatherArray[0]) // <--- This works?
}
} catch {
print("Did not work :(")
}
} ```
您的视图正在加载数据之前访问 weatherArray
。您需要考虑一个可能为空的数组以避免崩溃。
变化:
Text("\(weatherArray[0].name)") // <---- This doesn't work
收件人:
Text("\(weatherArray.first?.name ?? "")")
尝试使用此示例代码将天气数据导入您的模型并在您的视图中使用它:
public struct Weather: Identifiable, Codable {
public let id: Int
public let main, description, icon: String
}
struct Coord: Codable {
var lon: Double
var lat: Double
}
// holds all data from the JSON request
struct WeatherJSON: Codable {
var coord: Coord // coordinate struct
var weather: [Weather] // array of Weather struct
var base: String // "internal parameter..?"
var main: Main // main struct (contains the juicy data)
var visibility: Int // visibility number
var wind: Wind // wind struct
var clouds: Clouds // clouds struct
var dt: Int // time of data calculation, unix, UTC
var sys: Sys // internal parameer
var timezone, id: Int // timezone
var name: String // city namme
var cod: Int // another internal parameter (..?)
}
struct ContentView: View {
@State private var city: WeatherJSON?
var body: some View {
NavigationView {
VStack {
Text("\(city?.name ?? "no name")")
List {
ForEach(city?.weather ?? []) { weather in
Section(header:Text("Address")) {
Text("Current conditions: \(weather.main)")
.font(.headline)
.bold()
Text("Weather description: \(weather.description)")
.font(.body)
}
}
}
.navigationTitle("Weather")
}
}
.task { await handleData() }
}
func handleData() async {
guard let url = URL(string: "https://api.openweathermap.org/data/2.5/weather?q=Seattle&appid={apikey}") else {
print("This URL does not work!")
return
}
do {
let (weatherData, _) = try await URLSession.shared.data(from: url)
city = try JSONDecoder().decode(WeatherJSON.self, from: weatherData)
print(city)
} catch {
print("error: \(error)")
}
}
}
我正在创建一个天气应用程序。我使用 API (OpenWeatherApp) 来获取我的数据。我将数据加载到类型为 struct WeatherJSON
.
weatherArray
中
我可以使用 ForEach
循环成功访问数据,但是当我尝试使用 array[index]
直接访问特定数据时,出现以下错误:Thread 1: Fatal error: Index out of range
这是我正在使用的顶级结构:
// holds all data from the JSON request
struct WeatherJSON: Codable {
var coord: Coord // coordinate struct
var weather: [Weather] // array of Weather struct
var base: String // "internal parameter..?"
var main: Main // main struct (contains the juicy data)
var visibility: Int // visibility number
var wind: Wind // wind struct
var clouds: Clouds // clouds struct
var dt: Int // time of data calculation, unix, UTC
var sys: Sys // internal parameer
var timezone, id: Int // timezone
var name: String // city namme
var cod: Int // another internal parameter (..?)
}
我的内容视图:
struct ContentView: View {
@State private var weatherArray: [WeatherJSON] = []
// @State private var weatherArray: [Weather] = []
var body: some View {
NavigationView {
VStack {
Text("\(weatherArray[0].name)") // <---- This doesn't work
List {
// Text("Current conditions: \(weatherArray[0].description)")
// ForEach(weatherArray, id: \.self) { result in
// Section(header:Text("Address")) {
// Text("Current conditions: \(result.main)")
// .font(.headline)
// .bold()
// Text("Weather description: \(result.description)")
// .font(.body)
// }
// }
}
.navigationTitle("Weather")
}
}
.task { await handleData() }
}
func handleData() async {
guard let url = URL(string: "https://api.openweathermap.org/data/2.5/weather?q=Seattle&appid={APIKEY}") else {
print("This URL does not work!")
return
}
let decoder = JSONDecoder()
do {
let (weatherData, _) = try await URLSession.shared.data(from: url)
if let weatherObj = try? decoder.decode(WeatherJSON.self, from: weatherData) {
weatherArray.append(weatherObj)// = weatherObj.weather
print(weatherArray[0]) // <--- This works?
}
} catch {
print("Did not work :(")
}
} ```
您的视图正在加载数据之前访问 weatherArray
。您需要考虑一个可能为空的数组以避免崩溃。
变化:
Text("\(weatherArray[0].name)") // <---- This doesn't work
收件人:
Text("\(weatherArray.first?.name ?? "")")
尝试使用此示例代码将天气数据导入您的模型并在您的视图中使用它:
public struct Weather: Identifiable, Codable {
public let id: Int
public let main, description, icon: String
}
struct Coord: Codable {
var lon: Double
var lat: Double
}
// holds all data from the JSON request
struct WeatherJSON: Codable {
var coord: Coord // coordinate struct
var weather: [Weather] // array of Weather struct
var base: String // "internal parameter..?"
var main: Main // main struct (contains the juicy data)
var visibility: Int // visibility number
var wind: Wind // wind struct
var clouds: Clouds // clouds struct
var dt: Int // time of data calculation, unix, UTC
var sys: Sys // internal parameer
var timezone, id: Int // timezone
var name: String // city namme
var cod: Int // another internal parameter (..?)
}
struct ContentView: View {
@State private var city: WeatherJSON?
var body: some View {
NavigationView {
VStack {
Text("\(city?.name ?? "no name")")
List {
ForEach(city?.weather ?? []) { weather in
Section(header:Text("Address")) {
Text("Current conditions: \(weather.main)")
.font(.headline)
.bold()
Text("Weather description: \(weather.description)")
.font(.body)
}
}
}
.navigationTitle("Weather")
}
}
.task { await handleData() }
}
func handleData() async {
guard let url = URL(string: "https://api.openweathermap.org/data/2.5/weather?q=Seattle&appid={apikey}") else {
print("This URL does not work!")
return
}
do {
let (weatherData, _) = try await URLSession.shared.data(from: url)
city = try JSONDecoder().decode(WeatherJSON.self, from: weatherData)
print(city)
} catch {
print("error: \(error)")
}
}
}