I've had this problem a couple of times now, so thought I'd reach out.
I have a number of network interfaces responsible for making Async network calls, there's about 5/6 functions in each interface which all use a completion handler with the same definition:
(success: Bool, resources: [String: AnyObject] -> Void)
I'm looking for an alternative to adding this to the end of every function as it forces every function declaration onto 2/3 lines. e.g.
func performSomeNetworkCall(withThisParam parm1: AnyObject, param2: AnyObject, completion: (success: Bool, resources: [String: AnyObject] -> Void)) {
}
I've had a couple of ideas about how to solve the problem of long declarations and rewriting the completion definition for every function.
Thought One
Using a typealias
to define the closure like so:
typealias CompletionHandler = (success: Bool, resources: [String: AnyObject] -> Void)?
This, in theory, solves both issues as it's quick to write and solves the code length problems. However when calling function from an external source, the typealias
doesn't autocomplete like regular closures, meaning you have to write it out every-time leading to mistakes.
Thought Two
Using a code snippet (when Xcode actually remembers you set them). This in theory works as well, as long as every other developer working on the code also has the same code snippet and it aware of it instead of writing the entire declaration.
Thought Three
I thought about defining the completion handler as a function and passing the function as the parameter, something like this:
func completionHandler() -> (success: Bool, resources: [String: AnyObject] -> Void) {
return completionHandler()
}
But haven't been able to achieve what I wanted with that.
Edit
What I was hoping to achieve with Thought Three
func completionHandler() -> ((success: Bool, resources: [String: AnyObject]) -> Void) {
return completionHandler()
}
func networkCall(completion: (success: Bool, resources: [String: AnyObject]) -> Void) {
let request = NSURLRequest(URL: NSURL(string: "http://www.google.co.uk")!)
let session = NSURLSession.sharedSession()
session.dataTaskWithRequest(request) { (data, response, error) -> Void in
let handler = completionHandler()
handler(success: true, resources: [String: AnyObject]())
}
}
func foo() {
let handler = completionHandler()
networkCall(handler)
print(handler)
// hope to use handler.success || handler.resources here
}
Although currently just gets stuck on the completionHandler method call - (To point out the obvious...)