Xcode更新导致'dataTask(with:completionHandler:)'调用歧义错误?
问题:Xcode更新后URLSession dataTask闭包中guard语句触发编译错误
这段代码数月前可正常运行,推测因Xcode更新导致错误,且三处实现GitHub请求的同类代码均出现该问题,确认未修改相关代码。错误触发于let task = URLSession.shared.dataTask(with: request) { data, response, error in guard语句处。
原代码
func sendToGist(payload : GistExport.Output) { guard let data = encode(src: payload) else { print("no data") return } var urlString = "https://api.github.com/gists" if userProject!.gistID != nil {urlString += "/\(userProject!.gistID!)"} let url = URL(string: urlString)! var request = URLRequest(url: url) request.httpBody = data.data(using: String.Encoding.utf8) request.setValue("application/json", forHTTPHeaderField: "Content-Type") request.setValue("application/vnd.github+json", forHTTPHeaderField: "Accept") request.setValue("Bearer \(StartController.token)", forHTTPHeaderField: "Authorization") request.httpMethod = userProject?.gistID == nil ? "POST" : "PATCH" let task = URLSession.shared.dataTask(with: request) { data, response, error in guard let data = data, let response = response as? HTTPURLResponse, error == nil else { // check for fundamental networking error print("error", error ?? URLError(.badServerResponse)) return } guard (200 ... 299) ~= response.statusCode else { // check for http errors print("statusCode should be 2xx, but is \(response.statusCode)") print("response = \(response)") return } do { let decodedData = try JSONDecoder().decode(GistResult.self, from: data) print("done \(decodedData)") self.userProject!.updateCurrentID(decodedData.id) } catch { print(error) // parsing error if let responseString = String(data: data, encoding: .utf8) { print("responseString = \(responseString)") } else { print("unable to parse response as string") } } } task.resume() }
问题分析与解决方案
最可能的原因是闭包参数与内部变量重名:闭包传入的data、response、error参数,和guard语句中重新绑定的data、response变量同名。新版本Swift对变量命名的歧义检查更严格,因此触发编译错误。
修改方案:给闭包参数添加前缀或改名,避免与内部变量冲突:
let task = URLSession.shared.dataTask(with: request) { taskData, taskResponse, taskError in guard let data = taskData, let response = taskResponse as? HTTPURLResponse, taskError == nil else { print("error", taskError ?? URLError(.badServerResponse)) return } guard (200 ... 299) ~= response.statusCode else { print("statusCode should be 2xx, but is \(response.statusCode)") print("response = \(response)") return } do { let decodedData = try JSONDecoder().decode(GistResult.self, from: data) print("done \(decodedData)") self.userProject!.updateCurrentID(decodedData.id) } catch { print(error) if let responseString = String(data: data, encoding: .utf8) { print("responseString = \(responseString)") } else { print("unable to parse response as string") } } }
其他排查点
- 检查项目Swift版本:Xcode更新后项目的Swift语言版本可能自动升级,可在项目设置中确认是否与之前版本一致,若需兼容可尝试降级Swift版本。
- 查看具体错误提示:若编译错误提示为“ambiguous use of 'data'”,则可确认是变量重名问题,按上述方案修改即可。
- 批量处理同类代码:三处同类代码均存在该问题,可统一替换闭包参数命名,快速解决所有报错。
内容的提问来源于stack exchange,提问作者Dan Donaldson
相关产品推荐
相关产品推荐

