I have got a problem with displaying JSON data on a SwiftUI View. I tried several tutorials and read articles which are related to my problem, but nothing seems appropriate enough.
For example everyone displays JSON data from an API with a fancy list or pictures, but I only want to know how you can simply display one word on a view (without List{}
).
I chose the PokeAPI to figure out how to display "Hi Charmander" with the Text()
instruction.
Example of a list (and without ObservableObject
and @Published
)
I want to get rid of the List and use sth. Text(resultsVar[0].name).onAppear(perform: loadData)
like instead
import SwiftUI
struct pokeRequest:Codable {
var results: [Result]
}
struct Result:Codable {
var name:String
}
struct ViewOne: View {
@State var resultsVar = [Result]()
var body: some View {
VStack{
//unfortunately this does not work:
//Text(resultsVar[0].name).onAppear(perform: loadData)
List(resultsVar, id: \.name) { item in
VStack(alignment: .leading) {
Text("Hi \(item.name)")
}
}
.onAppear(perform: loadData)
}
}
func loadData(){
guard let url = URL(string: "https://pokeapi.co/api/v2/pokemon?offset=3&limit=3") else {
print("Invalid URL")
return
}
let request = URLRequest(url: url)
URLSession.shared.dataTask(with: request) { data, response, error in
if let data = data {
if let decodedResponse = try? JSONDecoder().decode(pokeRequest.self, from: data) {
DispatchQueue.main.async {
self.resultsVar = decodedResponse.results
}
return
}
}
print("Fetch failed: \(error?.localizedDescription ?? "Unknown error")")
}.resume()
}
}
struct ViewOne_Previews: PreviewProvider {
static var previews: some View {
ViewOne()
}
}
Second try with a different approach (without .onAppear()
)
In this approach I tried with class: Observable Object
and @Published
but I also didn't come to my wished UI-output.
import SwiftUI
struct pokeRequest2:Codable {
var results2: [pokeEach2]
}
struct pokeEach2:Codable {
var name2:String
}
class Webservice:ObservableObject {
@Published var pokeInfo: [pokeRequest2] = [pokeRequest2]()
func decodepokemon() {
let session = URLSession.shared
let url = URL(string: "https://pokeapi.co/api/v2/pokemon?offset=3&limit=3")!
let task = session.dataTask(with: url) { data, response, error in
if error != nil || data == nil {
print("Client error!")
return
}
guard let response = response as? HTTPURLResponse, (200...299).contains(response.statusCode) else {
print("Server error!")
return
}
guard let mime = response.mimeType, mime == "application/json" else {
print("Wrong MIME type!")
return
}
do {
let response = try JSONDecoder().decode(pokeRequest2.self, from: data!)
print(self.pokeInfo[0].results2[0].name2)
DispatchQueue.main.async {
self.pokeInfo = [response]
}
} catch {
print("JSON error: \(error.localizedDescription)")
}
}.resume()
}
init() {
decodepokemon()
}
}
struct ViewTwo: View {
@ObservedObject var webservice: Webservice = Webservice()
var body: some View {
Text("please help")
//Does also not work: Text(self.webservice.pokeInfo2[0].results2[0].name2)//.onAppear()
//Since a few minutes somehow the debug area prints "JSON error: The data couldn’t be read because it is missing." instead of "charmander"
}
}
struct ViewTwo_Previews: PreviewProvider {
static var previews: some View {
ViewTwo()
}
}
I tried several tutorials and read articles which are related to my problem, but nothing seems appropriate enough. I would highly appreciate any help :-) Thanks in advance!