Andrew Walz Andrew Walz - 3 years ago 212
Swift Question

Completion Handlers for Objective-C to Swift

I am currently rewriting a project from the Objective-C to Swift. Most of the project is done, but I am having problems translating a method that has a completion handler. I have reviewed the documentation, but I am still having problems. The method is:

- (void)start:(void ( ^ ) ( WTStartupConfiguration *configuration ))startupHandler
completion:(void ( ^ ) ( BOOL isRunning , NSError *error ))completionHandler


In objective-C, I would simply write is as:

[self.architectView start:^(WTStartupConfiguration *configuration)
{ } completion:^(BOOL isRunning, NSError *error) {}}];


I cannot get a good grasp on closure syntax in Swift. Any help would be appreciated!

Answer Source

You want something like this for your function:

func start(startupHandler:(configuration: WTStartupConfiguration)->(), completion:(isRunning:Bool, error:NSError?)->()) {

    let configuration = WTStartupConfiguration() // create your configuration

    startupHandler(configuration:configuration) // call your startup handler closure

    ... // do some stuff

    let isRunning = false // replace with actual logic
    let error = nil // replace with your actual error detection

    completion(isRunning: isRunning, error: error) // call completion closure
}

You can then call it like this:

start(
    { configuration in

        // do something with your configuration

    }, completion: {(isRunning, error) in

        // do something with your isRunning & error.

})

Closures are defined with the syntax (arguments) -> (returns), where you replace arguments with your inputs and returns with your outputs (much like how a function is defined).

In your case, your closures don't return anything, so we define them like:

(isRunning:Bool, error:NSError?) -> ()

(where () is shorthand for Void)

You then invoke them (if the argument types are known) using the short-hand notation of:

closureArgument: { (arguments here, without types as they're known) in

}

closureArgument: { (isRunning, error) in 

}

The more formal way of invoking them is:

closureArgument: { (arguments with types) -> (returns with types) in

}

closureArgument: { (isRunning:Bool, error:NSError?) -> () in 

}

I find this site is great to refer to for closure syntax (and can probably explain it better than me).

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download