Home > OS >  Struggling with rapid api and swiftui
Struggling with rapid api and swiftui

Time:10-08

Hi I am struggling with getting football data api from rapidapi to work in swift ui . here is the code below

The errors is get are "self.team = decodedTeams" Cannot find 'self' in scope"

and in my content view i get for " $network.getTeams" Value of type 'EnvironmentObject.Wrapper' has no dynamic member 'getTeams' using key path from root type 'Network'

I have set out what i have in 2 pages of my swiftui code below any help would be appreciated, I am really struggling with this one

//  Network.swift
//  Football Scores
//

//

import Foundation

class Network: ObservableObject {
        @Published var teams: [Team] = []

}
func getTeams() {
let headers = [
    "X-RapidAPI-Key": "MY API KEY",
    "X-RapidAPI-Host": "api-football-v1.p.rapidapi.com"
]`

let request = NSMutableURLRequest(url: NSURL(string: "https://api-football-v1.p.rapidapi.com/v3/standings?season=2022&league=39")! as URL,
                                  cachePolicy: .useProtocolCachePolicy,
                                  timeoutInterval: 10.0)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
    if (error != nil) {
        print(error)
    } else {
        let httpResponse = response as? HTTPURLResponse
        print(httpResponse)
        DispatchQueue.main.async {
                          do {
                              let decodedTeams = try JSONDecoder().decode([Team].self, from: data)
                              self.team = decodedTeams
                          } catch let error {
                              print("Error decoding: ", error)
                          }
                      }
    }
})

dataTask.resume()
}

and

//
//  Team.swift
//  Football Scores
//

//

import Foundation

struct Team: Identifiable, Decodable {
var id: Int
var name: String
var logo: String
var points: String
var goaldif: String
}

and

//  Football_ScoresApp.swift
//  Football Scores
//


import SwiftUI
import Foundation


@main

struct Football_ScoresApp: App {

var network = Network()

var body: some Scene {
    WindowGroup {
    
        ContentView()
                                       .environmentObject(network)
        }
    }

}

and

import SwiftUI
import CoreData

struct ContentView: View {
    @EnvironmentObject var network: Network


var body: some View {
    ScrollView {
                    Text("All teams")
                    .font(.title).bold()
            }
            .onAppear {
                network.getTeams()
            }
    VStack(alignment: .leading) {
        ForEach(network.teams) { team in
            HStack(alignment:.top) {
                Text("\(team.id)")

                VStack(alignment: .leading) {
                    Text(team.name)
                        .bold()

                   
                }
            }
            .frame(width: 300, alignment: .leading)
            .padding()
            .background(Color(#colorLiteral(red: 0.6667672396, green: 0.7527905703, blue: 1, alpha: 0.2662717301)))
            .cornerRadius(20)
        }
    }
    
}



}



struct ContentView_Previews: PreviewProvider {
static var previews: some View {
    ContentView()
        .environmentObject(Network())
    
}
}

CodePudding user response:

To display the teams from your api request, first you need to create a set of struct models that represent the json data that the server is sending. From the server response, you need to extract the teams information you want to display. Here is my code that shows how to do it, works well for me, pay attention to the details:

struct ContentView: View {
    @StateObject var network = Network() // <-- for testing

    var body: some View {
        List {
            VStack(alignment: .leading) {
                ForEach(network.teams) { team in
                    HStack(alignment:.top) {
                        Text("\(team.id)")
                        Text(team.name).bold()
                    }
                    .frame(width: 300, alignment: .leading)
                    .padding()
                    .background(Color(#colorLiteral(red: 0.6667672396, green: 0.7527905703, blue: 1, alpha: 0.2662717301)))
                    .cornerRadius(20)
                }
            }
        }
        .onAppear {
            network.getTeams()
        }
    }
    
}

class Network: ObservableObject {
    @Published var teams: [Team] = []
    
    func getTeams() {
        let token = "your-key"  // <--- here your api key

        guard let url = URL(string: "https://api-football-v1.p.rapidapi.com/v3/standings?season=2022&league=39") else { return }
        
        var request = URLRequest(url: url)
        request.httpMethod = "GET"
        request.setValue("\(token)", forHTTPHeaderField: "X-RapidAPI-Key")
        request.setValue("api-football-v1.p.rapidapi.com", forHTTPHeaderField: "X-RapidAPI-Host")
        
        URLSession.shared.dataTask(with: request) { data, response, error in
            guard let data = data else { return }
            DispatchQueue.main.async {
                do {
                    let results = try JSONDecoder().decode(FootyResponse.self, from: data)
                    // extract just the teams
                    for response in results.response {
                        for stand in response.league.standings {
                            for league in stand {
                                self.teams.append(league.team)
                            }
                        }
                    }
                } catch {
                    print(error) // <-- here important
                }
            }
        }.resume()
    }
  
}

// MARK: - FootyResponse
struct FootyResponse: Codable {
    let welcomeGet: String
    let parameters: Parameters
    let errors: [String]
    let results: Int
    let paging: Paging
    let response: [Response]

    enum CodingKeys: String, CodingKey {
        case welcomeGet = "get"
        case parameters, errors, results, paging, response
    }
}

// MARK: - Paging
struct Paging: Codable {
    let current, total: Int
}

// MARK: - Parameters
struct Parameters: Codable {
    let league, season: String
}

// MARK: - Response
struct Response: Codable {
    let league: League
}

// MARK: - League
struct League: Codable {
    let id: Int
    let name: String
    let country: String
    let logo: String
    let flag: String
    let season: Int
    let standings: [[Standing]]
}

// MARK: - Standing
struct Standing: Codable {
    let rank: Int
    let team: Team
    let points, goalsDiff: Int
    let group: String
    let form: String
    let status: String
    let standingDescription: String?
    let all, home, away: All
    let update: String  // <-- Date

    enum CodingKeys: String, CodingKey {
        case rank, team, points, goalsDiff, group, form, status
        case standingDescription = "description"
        case all, home, away, update
    }
}

// MARK: - All
struct All: Codable {
    let played, win, draw, lose: Int
    let goals: Goals
}

// MARK: - Goals
struct Goals: Codable {
    let goalsFor, against: Int

    enum CodingKeys: String, CodingKey {
        case goalsFor = "for"
        case against
    }
}

// MARK: - Team
struct Team: Identifiable, Codable {
    let id: Int
    let name: String
    let logo: String
}
  • Related