Reputation: 1592
Hi I have a web service worker object in swift that passes a completion block to the caller view controller. The code is as follows:
func getFlightData(for airportCode: String, minutesBehind:String, minutesAhead:String, completion: (([Flight], NSError) -> Void)?) {
var urlComponents = URLComponents()
urlComponents.scheme = "https"
urlComponents.host = "xxxxxxx.com"
urlComponents.path = "/1/airports/"+airportCode+"/flights/flightInfo"
urlComponents.queryItems = [
URLQueryItem(name: "city", value: airportCode),
URLQueryItem(name: "minutesBehind", value: minutesBehind),
URLQueryItem(name: "minutesAhead", value: minutesAhead)
]
guard let url = urlComponents.url else { fatalError("Could not create URL from components") }
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.setValue("xxxxxxxxx", forHTTPHeaderField: "Authorization")
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
let task = session.dataTask(with: request) { (responseData, response, responseError) in
DispatchQueue.main.async {
if let error = responseError {
//completion block???
}
else if let jsonData = responseData {
let decoder = JSONDecoder()
do {
let posts = try decoder.decode([Flight].self, from: jsonData)
//completion?(posts, nil) ???? what to pass for Error? Successful call
} catch {
self.showError()
}
}
else {
//completion block???
self.showError()
}
}
}
task.resume()
}
whatvalues do I pass in the completion blocks Error parameter when call is successful. I cant pass nil as swift does not let me do that. Can someone suggest a better way to make this API call? How to send completion block etc.
Upvotes: 0
Views: 1422
Reputation: 17050
Declare the completion block as taking an Error?
instead of an NSError
, and then you will be able to pass nil
to it in the success case. The ?
is what makes the parameter optional, which makes it possible for it to contain nil
. (Also, use Error
instead of NSError
, as it is the idiomatic Swift error type).
Alternatively, you can have your completion block take a Result
enum, which you can define like this:
public enum Result<T> {
case success(T)
case error(Error)
public func unwrap() throws -> T {
switch self {
case let .success(ret):
return ret
case let .error(error):
throw error
}
}
}
You can then use either the .success
or .error
cases, depending on whether the operation succeeded or failed.
Upvotes: 1
Reputation: 2343
It doesn't accept nil
because your parameter NSError
isn't optional.
Declare you method signature like
func getFlightData(for airportCode: String, minutesBehind:String, minutesAhead:String, completion: (([Flight], NSError?) -> Void)?) {
....
}
And it should work
Upvotes: 0