Hi guys,
since me Firebase works great I need one last step and that’s some JSON Data I have to parse.
I have a JSON which looks like this (“weights” with objects in it) and I need to display every single value of the array Items on its own. It’s hard because there are only tutorials for ListView etc. But I need single variables to display in ContentView.
I got stuck how I have to send the variables from “JSONManager” to “ContentView”
Items.swift look like this:
import Foundation
struct Weights: Codable {
let weights : [Items]
}
struct Items: Codable {
let oew: String
let pax_count: String
let bag_count: String
}
My JSONManager looks like this:
import Foundation
class JSONManager: ObservableObject {
@Published var weights : [Items]
init() {
fetchRemoteData()
}
func fetchRemoteData() {
let urlString = "https://www.simbrief.com/api/xml.fetcher.php?username=alancord&json=1"
let url = URL(string: urlString)
let defaultSession = URLSession(configuration: .default)
let dataTask = defaultSession.dataTask(with: url!) { data, response, error in
if error != nil {
print(error!.localizedDescription)
return
}
do {
let json = try JSONDecoder().decode(Weights.self, from: data!)
DispatchQueue.main.async {
self.weights = json.weights
}
} catch {
print(error.localizedDescription)
}
}
dataTask.resume()
}
}
ContentView looks like this:
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
Text("\(oew)")
Text("\(pax_count)")
Text("\(bag_count)")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Add a @StateObject
property for the JSON Manager to the content view.
@StateObject var jsonData: JSONManager
The @StateObject
property has the items you want to display.
1 Like
Thank you. I added it. You are right it is mandatory when I have a @Published Variable I need @StateObject somewhere else. Unfortunately I have many more errors…
import SwiftUI
struct ContentView: View {
@StateObject var jsonData: JSONManager
var body: some View {
VStack {
Text("\(jsonData.weights)")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView(jsonData: [Items])
}
}
You are going to need a ForEach
block to go through the items and create a view for each item. The code will look similar to the following:
var body: some View {
VStack {
ForEach(jsonData.weights, id: \.self) { weight in
Text(weight.oew)
Text(weight.pax_count)
Text(weight.bag_count)
}
}
}
You’re also going to have to call the fetchRemoteData
function to get data to show in the view. The most common way to do this is to add a .task
modifier to the view and make the call there.
1 Like
Thank you for the hint - do you know what I have to put in the Preview Part ?
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView(jsonData.content(Items)). // does not work Cannot find ‘jsonData’ in scope
}
}
You have to supply an instance of JSONManager
as the jsonData
argument for the content view in the preview.
ContentView(jsonData: JSONManager())
You might have to supply a weights
argument when calling the JSONManager
constructor.
You may also consider commenting out the preview part if you keep getting build errors because of an error in the preview code.
1 Like