SwiftUI异步方法执行顺序问题及Player属性访问异常排查
问题1:如何保证
fetchPlayerData在userToUUID获取到UUID后执行 你的代码里已经用await顺序调用了两个方法,但核心问题是**fetchPlayerData没有使用获取到的UUID**,且未处理userToUUID失败的情况。修改步骤如下:
修复
fetchPlayerData,绑定ViewModel中的UUID
替换硬编码的UUID,增加UUID为空的判断避免无效请求:func fetchPlayerData() async { guard !uuid.isEmpty else { print("UUID为空,无法获取玩家数据") return } let playersURLString = "https://api.hypixel.net/player?key=key&uuid=\(uuid)" if let url = URL(string: playersURLString) { do { let (data, _) = try await URLSession.shared.data(from: url) let decoder = JSONDecoder() player = try decoder.decode(ApiResponse.self, from: data).player print(player) apiLoaded = true } catch { print("获取玩家数据失败:\(error)") } } }增加流程判断,确保UUID获取成功后再执行后续请求
在task中判断UUID是否有效,无效则终止流程:ProgressView() .task { await vm.userToUUID(username: username) if !vm.uuid.isEmpty { await vm.fetchPlayerData() } else { print("获取UUID失败,终止流程") } }修复
userToUUID的URL拼接错误
原URL多了一个斜杠,修改为正确的拼接格式:let playersURLString = "https://api.mojang.com/users/profiles/minecraft/\(username)"
问题2:为什么
vm.player?.uuid无法工作,直接访问vm.uuid可行 核心原因有两点:
- 在
userToUUID方法执行时,player初始值为nil,所以player?.uuid = uuid这行代码会被可选链直接跳过,根本没有执行。 - 后续
fetchPlayerData直接将player赋值为API返回的对象,要么Hypixel API返回的player数据中没有uuid字段,要么你的Player模型中uuid字段的解码配置不匹配(比如字段名映射错误),导致player?.uuid始终为nil。 - 而
vm.uuid是你在userToUUID中直接赋值的独立属性,不受player对象的影响,因此可以正常访问。
如果想让vm.player?.uuid可用,可选择以下方案:
- 在
fetchPlayerData获取到player后,手动同步UUID:player = try decoder.decode(ApiResponse.self, from: data).player player?.uuid = self.uuid // 新增此行同步UUID - 检查
Player模型的解码配置,确保uuid字段与API返回的字段名匹配:struct Player: Codable { var uuid: String var displayname: String enum CodingKeys: String, CodingKey { case uuid = "id" // 若API返回的UUID字段名为id,需添加此映射 case displayname } }
内容的提问来源于stack exchange,提问作者Tom Miller
相关产品推荐
相关产品推荐

