Errors in ForEach SwiftUI

Hello
I get errors in ForEach that I don't know how to solve:

Generic struct 'ForEach' requires that 'Main' conform to 'RandomAccessCollection'
Unable to infer type of a closure parameter 'user' in the current context

Error at line 30 - 31

Code:
Code Block
//
// ContentView.swift
// ARWeather
//
// Created by Jad Taljabini on 08/04/21.
//
import SwiftUI
import Combine
struct ContentView: View {
@EnvironmentObject var networkController: NetworkControllerItalia
var body: some View {
NavigationView {
Form{
TextField("Input city name", text: $networkController.cityName, onEditingChanged: { te_xt in
networkController.url = URL(string: "https://api.openweathermap.org/data/2.5/weather?q=\(networkController.cityName)&appid=") ?? URL(string: "https://www.apple.com")!
networkController.fun()
}, onCommit: {
withAnimation{
networkController.url = URL(string: "https://api.openweathermap.org/data/2.5/weather?q=\(networkController.cityName)&appid=") ?? URL(string: "https://www.apple.com")!
networkController.fun()
}
})
Section {
ForEach(networkController.users.weather ?? [], id: \.self){ user in
Text(user.main ?? "")
}
ForEach(networkController.users.main ?? Main(temp: 0), id: \.self){ user in
Text("\(user.temp)")
}
}
}
}
}
}
class NetworkControllerItalia: ObservableObject {
private var can: AnyCancellable?
@Published var cityName: String = ""
@Published var users = UserItalia(weather: [])
var url = URL(string: "https://www.apple.com")!
func fun(){
self.can = URLSession.shared.dataTaskPublisher(for: url)
.map { $0.data }
.decode(type: UserItalia.self, decoder: JSONDecoder())
.eraseToAnyPublisher()
.receive(on: DispatchQueue.main)
.sink(receiveCompletion: {completion in
print(completion)
}, receiveValue: { users in
self.users = users
})
}//Funzione che riempe users di dati da internet
}
struct UserItalia: Decodable, Hashable{
var weather: [Weather]?
var main: Main?
}
struct Weather: Decodable, Hashable {
var main: String?
}
struct Main: Decodable, Hashable {
var temp: Float
}

The JSON API is like this:
Code Block {
"coord": {
"lon": -0.1257,
"lat": 51.5085
},
"weather": [
{
"id": 801,
"main": "Clouds",
"description": "few clouds",
"icon": "02d"
}
],
"base": "stations",
"main": {
"temp": 285.45,
"feels_like": 283.96,
"temp_min": 284.82,
"temp_max": 285.93,
"pressure": 1021,
"humidity": 47
},
"visibility": 10000,
"wind": {
"speed": 5.66,
"deg": 220
},
"clouds": {
"all": 20
},
"dt": 1617888145,
"sys": {
"type": 1,
"id": 1414,
"country": "GB",
"sunrise": 1617859180,
"sunset": 1617907473
},
"timezone": 3600,
"id": 2643743,
"name": "London",
"cod": 200
}

Thank you
Answered by Claude31 in 670021022
That's the problem with such complex definitions in your code…

There is probably a missing parenthesis before .temp (to be balanced by another leading one.

Code Block
Text( "\(( networkController.users.main ?? Main(temp: 0)).temp)")

I don't understand what you want to show in Section and what you do in ForEach.

In addition, your naming of var is awfully confusing
  • main used in different places for different things

  • users as plural but not an array…

  • weather singular but several values in array

If I understand what you want to do, you should probably:
Code Block
Section {
ForEach(networkController.users.weather ?? [], id: \.self){ userWeather in // rename user
Text(userWeather.main ?? "")
}
// ForEach is meaningless here ForEach(networkController.users.main ?? Main(temp: 0), id: \.self){ user in
// Text("\(user.temp)")
Text( "\(networkController.users.main ?? Main(temp: 0)).temp)")
}



Text( "\(networkController.users.main ?? Main(temp: 0).temp)")

Gives some errors:

Cannot convert value of type 'Float' to expected argument type 'Main'
Instance method 'appendInterpolation' requires that 'Main' conform to '_FormatSpecifiable'

But yes, (this: Text( "\(networkController.users.main ?? Main(temp: 0).temp)")), this is what I want to do.
Accepted Answer
That's the problem with such complex definitions in your code…

There is probably a missing parenthesis before .temp (to be balanced by another leading one.

Code Block
Text( "\(( networkController.users.main ?? Main(temp: 0)).temp)")

Errors in ForEach SwiftUI
 
 
Q