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?#>))
CodePudding user response:
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.