Completion Handlers for Objective-C to Swift

 ̄綄美尐妖づ 提交于 2019-12-19 04:51:34

问题


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!


回答1:


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 an empty tuple () is used to show that nothing is returned)

You then create them, and pass them into functions (if the argument types of the closure 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 passing them into a function is:

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

}

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

}

You can then invoke the closure in pretty much the same way that you call functions.

closureArgument(isRunning: false, error: nil)

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




回答2:


I'm sure others will give you very detailed answers with example code, so I'll just mention this for future reference:

How Do I Declare a Closure in Swift?

From fuckingclosuresyntax.com or the SFW version goshdarnclosuresyntax.com.

As a variable:

var closureName: (ParameterTypes) -> (ReturnType)

As an optional variable:

var closureName: ((ParameterTypes) -> (ReturnType))?

As a type alias:

typealias ClosureType = (ParameterTypes) -> (ReturnType)

As a constant:

let closureName: ClosureType = { ... }

As an argument to a function call:

func({(ParameterTypes) -> (ReturnType) in statements})

As a function parameter:

array.sort({ (item1: Int, item2: Int) -> Bool in return item1 < item2 })

As a function parameter with implied types:

array.sort({ (item1, item2) -> Bool in return item1 < item2 })

As a function parameter with implied return type:

array.sort({ (item1, item2) in return item1 < item2 })

As the last function parameter:

array.sort { (item1, item2) in return item1 < item2 }

As the last parameter, using shorthand argument names:

array.sort { return $0 < $1 }

As the last parameter, with an implied return value:

array.sort { $0 < $1 }

As the last parameter, as a reference to an existing function:

array.sort(<)

As a function parameter with explicit capture semantics:

array.sort({ [unowned self] (item1: Int, item2: Int) -> Bool in return item1 < item2 })

As a function parameter with explicit capture semantics and inferred parameters / return type:

array.sort({ [unowned self] in return item1 < item2 })

This site is not intended to be an exhaustive list of all possible uses of closures.




回答3:


For you to understand how the closure works, I have separated the definition of closures and not defining it inline to the method signature. You could do the following:

func start(startupHandler: (configuration: WTStartupConfiguration) -> Void, completion: (isRunning: Bool, error: NSError) -> Void ) {
    //Your code for start method
}

var startupHandlerClosure = { (configuration: WTStartupConfiguration) -> Void in
    //Your code for startupHandler closure
}

var completionClosure = { (isRunning: Bool, error: NSError) -> Void in
    //Your code for completion closure
}

//Method call
start(startupHandlerClosure, completion: completionClosure)

@originaluser2 beat me to it.. he provides example with additional code.



来源:https://stackoverflow.com/questions/35420548/completion-handlers-for-objective-c-to-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!