Home > OS >  SwiftUI : Can't receive API response
SwiftUI : Can't receive API response

Time:09-15

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

  • Related