You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI异步方法执行顺序问题及Player属性访问异常排查

问题1:如何保证fetchPlayerData在userToUUID获取到UUID后执行

你的代码里已经用await顺序调用了两个方法,但核心问题是**fetchPlayerData没有使用获取到的UUID**,且未处理userToUUID失败的情况。修改步骤如下:

  1. 修复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)")
            }
        }
    }
    
  2. 增加流程判断,确保UUID获取成功后再执行后续请求
    在task中判断UUID是否有效,无效则终止流程:

    ProgressView()
        .task {
            await vm.userToUUID(username: username)
            if !vm.uuid.isEmpty {
                await vm.fetchPlayerData()
            } else {
                print("获取UUID失败,终止流程")
            }
        }
    
  3. 修复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可用,可选择以下方案:

  1. 在fetchPlayerData获取到player后,手动同步UUID:
    player = try decoder.decode(ApiResponse.self, from: data).player
    player?.uuid = self.uuid // 新增此行同步UUID
    
  2. 检查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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 21:48:27