swift argument type () -> () - swift

func speak(text:String, onComplete:()->()) {
mySpeechUtterance = AVSpeechUtterance(string: text)
mySpeechSynthesizer.speakUtterance(mySpeechUtterance)
onComplete()
}
My question is: How can I call this method?
speechSynthesizer.speak(actions[0], onComplete: "here")

Pass a closure.
speechSynthesizer.speak(actions.first) {
// code to be executed after speaking
}
This is the same as
speechSynthesizer.speak(actions.first, onComplete: {
// code to be executed after speaking
})
but obviously, the trailing closure syntax looks much cleaner.
Explanation:
the first part () means "a function without arguments",
the second part -> () means "without return value".

There is a number of options. The simplest in this case is considering that onComplete is the last closure the next one:
speechSynthesizer.speak(actions[0]) {
# onComplete code goes here
}
On remark to the function definition in your question. It should probably be
func speak(text:String, onComplete: () -> Void) {...}

Related

How to call a parameter label of type closure (Swift)

Closures As Parameters
let driving = {
print("I'm driving in my car.")
}
func travel(action: () -> Void) {
print("I'm getting ready to go.")
action()
print("I arrived!")
}
travel(action: driving)
action is a parameter label. How come we consider it as a function call as in action()?
Lets look at a brief example:
func myFunction() {...} Swift sees this as () -> Void
the same way that Swift sees this "John" as String
So when you write a function like myFunction you could really say
func myFunction() -> Void {...} for the same result.
Now action is defined as a parameter as a function but the type that it accepts for that parameter is () -> Void aka a closure which for now you can think of just another function.
So the line action() is just the call of that function.
But be sure to read up on functions accepted as parameters

Is a closure that is passed in as a parameter assigned to the parameter name in swift?

This code is from this blog.
Is the reason we can call completion() because the closure that's passed in () -> () is essentially assigned to the parameter completion and so calling completion executes the closure?
func thisNeedsToFinishBeforeWeCanDoTheNextStep(completion: () -> ()) {
print("The quick brown fox")
completion()
}
func thisFunctionNeedsToExecuteSecond() {
print("jumped over the lazy dog")
}
If that's the case re: calling the function below I don't quite get how the code below translates into the first function being called and completed before the thisFunctionNeedsToExecuteSecond() is? What I mean by that is how is the ()->() in resulting in the completion() executing before thisFunctionNeedsToExecuteSecond() is called - it's hard explaining this in writing.
thisNeedsToFinishBeforeWeCanDoTheNextStep { () -> () in
thisFunctionNeedsToExecuteSecond()
}
If you create a function with a closure as one of its input parameters, the closure is executed as soon as you call it by inputParameterName(). The parentheses after the name of the input parameter mark the function call with no input parameters to the closure, since its type in your case is Void->Void.
In your second example,
thisNeedsToFinishBeforeWeCanDoTheNextStep { () -> () in
thisFunctionNeedsToExecuteSecond()
}
you see a trailing closure. If the last input parameter of a function is a closure, the function call can be converted to the trailing closure syntax, where you can omit the name of the closure (completion in your case) and the code between the {} will be executed once the closure is called.
So the above code is equivalent to
thisNeedsToFinishBeforeWeCanDoTheNextStep(completion: { () -> () in
thisFunctionNeedsToExecuteSecond()
})

Swift lambda gets inserted into end of argument list

With Swift 3.1
func foo() {
{ () -> Void in
print("oh, nice, now this works too!!!")
}()
}
foo()
works... but
func foo() {
print("Hi!")
{ () -> Void in
print("oh, nice, now this works too!!!")
}()
}
foo()
Will cause
ERROR at line 2, col 2: cannot invoke 'print' with an argument list
of type '(String, () -> Void)'
That can be fixed inserting semicolon after print
print("Hi!");
or parenthesis around the lambda definition. However, what I'm interested in is what is the root cause of the behaviour from the Swift compiler perspective?
In the second case, you need to separate the print call from the lambda block.
First case:
func foo() { () -> () }
No problem you can do whatever you want in your closure
Second case:
The compiler thinks you're telling the print statement to execute your closure after it ended.
So you need to separate with semicolon your print("hi") statement or wrap the lambda block to be explicit.

How to create function with two closures as params in Swift?

I need to translate such a func from Objective-C to Swift language. But can't find an example and can't get how to send 2 closures into func in Swift.
For example, original function in Objective-C:
- (void)getForDemoDataWithToken:(Token *)token
onSuccess:(void(^)(NSArray *demoData))success
onFailure:(void(^)(NSError *error))failure {
}
I know to send 1 closure as param:
getForDemoDataWithToken(token) {(success: String) -> Void in
// some code here
print(success)
}
But, how to send two closures?
Thank you
What about this?
Declaration
func getForDemoDataWithToken(
token: Token,
onSuccess: (demoData:NSArray?) -> (),
onFailure: (error:NSError?) -> ()) {
}
Invocation
getForDemoDataWithToken(Token(),
onSuccess: { (demoData) -> () in
},
onFailure: { (demoData) -> () in
}
)
A more Swifty approach
I usually see Swift code where only one closure is used. So instead of 2 distinct onSuccess and onFailure closures you could have just completion.
Next we should remember that NSArray is compatible with Swift but it's not the Swiftest way to use an array.
Let's see an example where the 2 concepts above are applied.
func getForDemoData(token:Token, completion:(data:[Foo]?, error:NSError?) -> ()) {
}
You can invoke it with the trailing closure syntax.
getForDemoData(Token()) { (data, error) -> () in
if let data = data where error == nil {
// success!
} else {
// oh no... something wrong here
}
}
You should pass the closures as normal parameters, like this:
func acceptsTwoClosures(
onSuccess onSuccess: (success: String) -> Void,
onFailure: (failure: String) -> Void) {
onSuccess(success: "Ook")
onFailure(failure: "Eek")
}
acceptsTwoClosures(
onSuccess: { print("Success: \($0)") },
onFailure: { print("Failure: \($0)") }
)
// In the playground the above prints:
//
// Success: Ook
// Failure: Eek
The way that you used in the question is called trailing closure, and it only works for the closures that are the last arguments in the function signature.
From the documentation:
If you need to pass a closure expression to a function as the function’s final argument and the closure expression is long, it can be useful to write it as a trailing closure instead. A trailing closure is a closure expression that is written outside of (and after) the parentheses of the function call it supports.
For example, you could also re-write my suggested snippet from above like this:
acceptsTwoClosures(onSuccess: { print("Success: \($0)") }) {
print("Failure: \($0)")
}
.. as you can see, I can pass the second (i.e. the last) closure outside of acceptsTwoClosures call as a trailing closure, but I still have to pass the first one as a normal parameter.

Is there a shorthand for a function that takes no parameters and returns nothing? AKA () -> ()

The title says it all, I believe. I'm simply curious if the () -> () acting as a function's parameter...
class Test {
var isAwesome = true
func loadData (callback: () -> ()) {
callback();
}
}
... has a shorter version. That's it!
I'm not sure if there is a "Swift-way" to do it, but if you really want to shorten it:
typealias A = ()->() // alias this closure risking readability
class Test {
func loadData (callback:A) {
callback();
}
}
It is a bit of a hack I suppose.
As found in: Apple Inc. 'The Swift Programming Language'. iBooks. https://itun.es/nl/jEUH0.l
You can use the following syntax:
func someFunctionThatTakesAClosure(closure: () -> ()) {
// function body goes here
}
// here's how you call this function without using a trailing closure:
someFunctionThatTakesAClosure({
// closure's body goes here
})
// here's how you call this function with a trailing closure instead:
someFunctionThatTakesAClosure() {
// trailing closure's body goes here
}
I cannot find any documentation that specifies a different solution. Every instance I can find in the current docs/book shows it how you have it. Here is a good section that talks about it. You can however call your method with some pretty short notation:
loadData {
// ...
}
Rather than having to treat it as a normal parameter:
loadData({
// ...
})
You can also call it like:
loadData() {
// ...
}
I think there is no shorter-way: I can just imagine a type-alias (like #Benzi mentioned), but the effect seems not worth the hack.
func takeEmptyFunc(emptyFunc: ()->()) { emptyFunc() }
func emptyFunc() { println("Worked"); }
takeEmptyFunc() { emptyFunc() } // prints "Worked"