I'm trying to get a response from this link : https://zsr.octane.gg/players/5f5ae840c6cbf591c568a477 but it won't work and I can't figure why.
There is my ContentView.swift :
struct ContentView: View {
@State private var players = [Player]()
var body: some View {
List(players, id: \._id) { item in
VStack(alignment: .leading) {
Text(item.name)
.font(.headline)
Text(item.country)
}
}.task {
await loadData()
}
}
func loadData() async {
guard let url = URL(string: "https://zsr.octane.gg/players/5f5ae840c6cbf591c568a477") else {
print("URL invalide")
return
}
do {
let (data, _) = try await URLSession.shared.data(from: url)
if let decodedResponse = try? JSONDecoder().decode(Response.self, from: data) {
players = decodedResponse.players
}
} catch {
print("Invalid data")
}
}
}
My Response struct :
struct Response: Codable {
var players: [Player]
}
Player struct :
struct Player: Codable {
var _id: String
var slug: String
var tag: String
var name: String
var country: String
var team: Team
var accounts: [Account]
var revelant: Bool
}
Team struct :
struct Team: Codable {
var _id: String
var slug: String
var name: String
var region: String
var image: String
var relevant: Bool
}
Account struct :
struct Account: Codable {
var platform: String
var id: String
}
Edit: the error that I have from the do catch
is :
Invalid data with error: keyNotFound(CodingKeys(stringValue: "revelant", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: "revelant", intValue: nil) ("revelant").", underlyingError: nil))
I followed a tutorial which works well but when I replace the link and use my own structs nothing happens when I launch the app. Thanks for your help.
CodePudding user response:
Your response is a dictionary not an array to to log error use try
instead of try?
and log the error inside the catch part , this snippet is after the edit and it shows currently info of 1 player
One player
func loadData() async {
guard let url = URL(string: "https://zsr.octane.gg/players/5f5ae840c6cbf591c568a477") else {
print("URL invalide")
return
}
do {
let (data, _) = try await URLSession.shared.data(from: url)
let decodedResponse = try JSONDecoder().decode(Player.self, from: data)
players = [decodedResponse]
} catch {
print("Invalid data with error: ",error)
}
}
All players
May be you mean to drop 5f5ae840c6cbf591c568a477
from guard let url = URL(string: "https://zsr.octane.gg/players/5f5ae840c6cbf591c568a477") else {
to get all players , check here complete working demo
import SwiftUI
struct ContentView: View {
@State private var players = [Player]()
var body: some View {
List(players, id: \._id) { item in
VStack(alignment: .leading) {
Text(item.name ?? "")
.font(.headline)
Text(item.country ?? "")
}
}.task {
await loadData()
}
}
func loadData() async {
guard let url = URL(string: "https://zsr.octane.gg/players") else {
print("URL invalide")
return
}
do {
let (data, _) = try await URLSession.shared.data(from: url)
let decodedResponse = try JSONDecoder().decode(Response.self, from: data)
players = decodedResponse.players
} catch {
print("Invalid data",error)
}
}
}
struct Response: Codable {
var players: [Player]
}
struct Player: Codable {
var _id: String
var slug: String
var tag: String
var name: String?
var country: String?
var accounts: [Account]?
}
struct Team: Codable {
var _id: String
var slug: String
var name: String
var region: String
var image: String
var relevant: Bool
}
struct Account: Codable {
var platform: String
var id: String
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Note: a variable that may exist in a model or not should be marked as optional