swift - Cannot convert value of type '()' to expected argument type '(Data?, URLResponse?, Error?) -> Void'
问题描述
I can't solve this error I hope can I find the solution here
the error is in the line 22 and it's "Cannot convert value of type ()
to expected argument type (Data?, URLResponse?, Error?) -> Void
"
struct WeatherManager {
let weatherURL = ""
func fetchWeather(cityName : String){
let urlString = "\(weatherURL)&q=\(cityName)"
performRequest(urlString: urlString)
}
func performRequest(urlString : String){
//1- Create a URL
if let url = URL(string: urlString){
//2- Create a URLSession
let session = URLSession(configuration: .default)
//3- Give the session a task
let task = session.dataTask(with: url, completionHandler:handel(data: <#T##Data?#>, urlSession: <#T##URLSession?#>, error: <#T##Error?#>))
//4- Start the Task
task.resume()
}
}
func handel(data:Data? , urlSession : URLSession? , error : Error?){
if error != nil {
print(error!)
return
}
if let safeData = data{
let dataString = String(data: safeData, encoding: .utf8)
print(dataString!)
}
}
}
here is the error :
let task = session.dataTask(with: url, completionHandler:handel(data: <#T##Data?#>, urlSession: <#T##URLSession?#>, error: <#T##Error?#>))
解决方案
A few observations:
The signature of “handle” is incorrect. The second parameter is a
URLResponse
, not aURLSession
:func handle(data: Data?, response: URLResponse?, error: Error?) { if let error = error { print(error) return } if let data = data, let string = String(data: data, encoding: .utf8) { print(string) } }
As Leo pointed out, you should avoid force-unwrapping with the
!
operator, too (especially when converting theData
to a UTF8String
).You should not supply parameters when you pass
handle
todataTask
:func performRequest(urlString: String) { //1- Create a URL guard let url = URL(string: urlString) else { return } //2- Use existing URLSession let session = URLSession.shared // (configuration: .default) //3- Give the session a task let task = session.dataTask(with: url, completionHandler: handle) //4- Start the Task task.resume() }
Unrelated, please note that I have not created a URLSession
in performRequest
. Sessions will leak memory if you create them but do not invalidate them. In this case, it is easier to use the existing shared
session, rather than creating a new one.
If you really needed to create one (which you obviously do not in this case ... use shared
instead), you would explicitly tell it to invalidate itself when the request was done.
func performRequest(urlString: String) {
//1- Create a URL
guard let url = URL(string: urlString) else { return }
//2- Create URLSession (but only if absolutely necessary)
let session = URLSession(configuration: .default)
//3- Give the session a task
let task = session.dataTask(with: url, completionHandler: handle)
//4- Start the Task
task.resume()
//5- If you really must create a session, invalidate it when the request(s) are finished
session.finishTasksAndInvalidate()
}
But this is an anti-pattern because it is so inefficient. You should reuse a single session, like shown in the previous code snippet, if at all possible.
推荐阅读
- javascript - XSJS 从变量中的存储过程获取结果
- node.js - 使用 DynamoDB Docker 容器的 Github 操作
- excel - VBA:仅向 excel 组合框添加唯一值,该组合框通过在工作簿打开时循环访问源工作表范围来填充
- java - Flurry 测试推送通知来了,但是campain 通知不来
- coldfusion - CFWheels 错误:元素 RETURNVALUE 在 LOC 中未定义
- javascript - 从标题下的降价列表中获取每个项目
- java - 安装了 JDK 8 的“警告:发生了非法反射访问操作”
- html - 发生错误后如何通过代码将已经打开的网页重新设置为焦点
- python - 为什么 Django 抱怨一个新的模型列是未知的而不是迁移它?
- sml - 如何与 SML 和 CM 共享数据类型声明