SwiftUI使用Alamofire请求RAWG游戏详情如何传入列表选中的动态ID
解决方案
你只需要修改2个文件的代码,就可以实现传入动态选中的游戏ID拉取对应详情:
第一步:修改ApiServiceDetail.swift
把原本写死ID的初始化方法改成支持动态传入ID:
import Foundation import Alamofire class ApiServiceDetail: ObservableObject { @Published var gameDetail = DetailGame(id: 0, name: "", backgroundImage: "", description: "", website: "" ) @Published var loading = false private let apiKey = "?key=MY_KEY" private let apiURLBase = "https://api.rawg.io/api/games/" // 修改初始化方法,支持传入动态ID init(id: Int) { loading = true loadDataByAlamofire(id: id) } private func loadDataByAlamofire(id: Int) { AF.request("\(apiURLBase)\(id)\(apiKey)") .responseJSON { response in switch response.result { case .success: print("Success Get Data") guard let data = response.data else { return } do { let detailGames = try JSONDecoder().decode(DetailGame.self, from: data) DispatchQueue.main.async { self.gameDetail = detailGames self.loading = false } } catch { // 处理解析错误,避免try!崩溃 print("解析数据失败: \(error)") DispatchQueue.main.async { self.loading = false } } case .failure(let error): print("Error Connect to Server: \(error)") DispatchQueue.main.async { self.loading = false } } } } }
这里额外优化了原代码的try!强制解析,替换为do-catch捕获异常,避免数据格式异常时直接闪退
第二步:修改GameDetail.swift
将页面接收的选中游戏ID,传递给ApiServiceDetail初始化方法:
import SwiftUI import URLImage import Alamofire struct GameDetail: View { @ObservedObject var apiServiceDetail: ApiServiceDetail var idGame: Int // 自定义初始化方法,传入id后初始化请求类 init(idGame: Int) { self.idGame = idGame self.apiServiceDetail = ApiServiceDetail(id: idGame) } var body: some View { ScrollView { // 新增加载状态提示 if apiServiceDetail.loading { ProgressView("加载游戏详情中...") .frame(maxWidth: .infinity, maxHeight: .infinity) .padding(.top, 100) } else { VStack (alignment: .leading) { URLImage(URL(string: "\(apiServiceDetail.gameDetail.backgroundImage)")!) { image in image .resizable() .aspectRatio(contentMode: .fill) .border(Color.gray.opacity(0.5)) .offset(x: 0, y: 0) .padding(.bottom, 0) .frame(width: UIScreen.main.bounds.height/8*3, height: UIScreen.main.bounds.height/2) } Text("\(apiServiceDetail.gameDetail.name)") .font(.system(size: 25)) .bold() Spacer() Text("Website") .bold() Text("\(apiServiceDetail.gameDetail.website)") .foregroundColor(.blue) .underline() .onTapGesture { UIApplication.shared.open(URL(string: "\(apiServiceDetail.gameDetail.website)")!, options: [:]) } Spacer(minLength: 10) Text("Description") .bold() Text(apiServiceDetail.gameDetail.description) } } } .navigationBarTitle(Text(apiServiceDetail.gameDetail.name), displayMode: .inline) .padding() } }
这里额外加了加载状态的ProgressView,避免接口请求过程中页面空白
修改完成后,你从列表页点击任意游戏,都会把对应游戏的ID传入详情接口拉取对应数据,不需要再写死固定ID。
内容的提问来源于stack exchange,提问作者beginner
相关产品推荐
相关产品推荐

