SwiftUI集成RapidAPI足球数据接口遇错误求助
问题解决:SwiftUI调用RapidAPI足球数据接口的错误修复
错误1:Cannot find 'self' in scope
原因
getTeams()函数定义在Network类外部,不属于类的成员方法,无法访问类实例的self- 代码中误写属性名:
self.team应该是self.teams(类中定义的是@Published var teams: [Team] = [])
修复
将getTeams()移到Network类内部作为实例方法,同时修正属性名:
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" ] guard let url = URL(string: "https://api-football-v1.p.rapidapi.com/v3/standings?season=2022&league=39") else { print("Invalid URL") return } var request = URLRequest(url: url, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0) request.httpMethod = "GET" request.allHTTPHeaderFields = headers let session = URLSession.shared let dataTask = session.dataTask(with: request) { [weak self] data, response, error in if let error = error { print(error) return } guard let data = data else { print("No data received") return } DispatchQueue.main.async { do { // 匹配RapidAPI实际返回的JSON结构 let apiResponse = try JSONDecoder().decode(APIResponse.self, from: data) self?.teams = apiResponse.response.first?.league.standings.first?.map { $0.team } ?? [] } catch let error { print("Error decoding: ", error) // 打印原始JSON辅助调试 if let jsonString = String(data: data, encoding: .utf8) { print("Raw JSON: \(jsonString)") } } } } dataTask.resume() } }
错误2:Value of type 'EnvironmentObject.Wrapper' has no dynamic member 'getTeams'
原因
之前getTeams()不是Network类的成员方法,导致@EnvironmentObject实例无法找到该方法。
修复
完成上述类方法迁移后,ContentView中的network.getTeams()调用即可正常工作,无需额外修改(确保代码中是network.getTeams()而非$network.getTeams())。
额外修复:JSON解码结构不匹配
RapidAPI足球接口返回的是嵌套JSON结构,需补充对应模型才能正确解码:
// 新增API响应层级模型 struct APIResponse: Decodable { let response: [LeagueResponse] } struct LeagueResponse: Decodable { let league: League } struct League: Decodable { let standings: [[Standing]] } struct Standing: Decodable { let team: Team let points: String let goaldif: String } // 修正Team模型,匹配接口字段 struct Team: Identifiable, Decodable { let id: Int let name: String let logo: String }
布局优化(可选)
ContentView中ScrollView和VStack并列会导致布局错位,建议将VStack移入ScrollView:
struct ContentView: View { @EnvironmentObject var network: Network var body: some View { ScrollView { Text("All teams") .font(.title).bold() .padding() VStack(alignment: .leading, spacing: 16) { 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) } } .padding() } .onAppear { network.getTeams() } } }
内容的提问来源于stack exchange,提问作者Sean Watson
相关产品推荐
相关产品推荐

