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
相关产品推荐
相关产品推荐

