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

Swift中URLSession报cannot find 'self' in scope及状态码处理问题

问题1:self报错的原因

你当前定义的downloadPlayerSummaries是全局函数,不属于任何类/结构体,自然不存在self这个实例指向。你参考的官方示例代码是把网络请求逻辑写在自定义类内部的,self原本指向的是那个类的实例,handleClientError、handleServerError也都是示例里自定义的错误处理方法,不是系统提供的API,你没有定义这两个方法自然会报错。

问题2:错误处理与HTTP状态码处理方案

你可以直接在全局函数内实现错误处理逻辑,不用依赖类方法,同时需要注意网络请求是异步操作,不能直接同步返回结果,需要用闭包回调传递数据,修改后的代码示例如下:

func downloadPlayerSummaries(with url: URL?, completion: @escaping (Result<Data, Error>) -> Void) {
    // 先校验URL合法性
    guard let url = url else {
        completion(.failure(NSError(domain: "SteamNetwork", code: -1, userInfo: [NSLocalizedDescriptionKey: "请求URL为空"])))
        return
    }
    let task = URLSession.shared.dataTask(with: url) { data, response, error in
        // 处理客户端侧错误(无网络、超时、域名无法解析等)
        if let error = error {
            completion(.failure(error))
            return
        }
        // 校验响应格式是否为HTTP
        guard let httpResponse = response as? HTTPURLResponse else {
            completion(.failure(NSError(domain: "SteamNetwork", code: -2, userInfo: [NSLocalizedDescriptionKey: "非HTTP格式响应"])))
            return
        }
        // 校验HTTP状态码,2xx区间为请求成功
        guard (200...299).contains(httpResponse.statusCode) else {
            let errInfo = [NSLocalizedDescriptionKey: "请求失败,HTTP状态码:\(httpResponse.statusCode)"]
            completion(.failure(NSError(domain: "SteamNetwork", code: httpResponse.statusCode, userInfo: errInfo)))
            return
        }
        // 校验响应数据非空
        guard let data = data else {
            completion(.failure(NSError(domain: "SteamNetwork", code: -3, userInfo: [NSLocalizedDescriptionKey: "响应数据为空"])))
            return
        }
        // 所有校验通过,返回响应数据
        completion(.success(data))
    }
    task.resume()
}

问题3:调用逻辑修正

因为网络请求是异步执行的,你不能直接拿到返回值打印,需要在回调闭包里处理结果,AppDelegate内的调用代码修改如下:

func applicationDidFinishLaunching(_ aNotification: Notification) {
    var apiKey: String = "[REDACTED]"
    var steamID: String = "[REDACTED]"
    let getPlayerSummaries = URL(string: "http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=\(apiKey)&steamids=\(steamID)")
    
    downloadPlayerSummaries(with: getPlayerSummaries) { result in
        DispatchQueue.main.async { // 涉及UI操作需要切回主队列
            switch result {
            case .success(let data):
                // 可在这里将data转为JSON字典做后续处理
                if let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any] {
                    print("请求成功,返回数据:\(json)")
                }
            case .failure(let error):
                print("请求失败:\(error.localizedDescription)")
            }
        }
    }
}

内容的提问来源于stack exchange,提问作者Soulfire J. Backblaze

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 23:24:03