Reputation: 957
I want to implement a callback in a swift project just like I used to do in Objective-C I need a variable of type closure. That closure should take as a parameter an object and return nothing.
var downloadCompleted: (MLBook) -> (Void)!
When I need to trigger the callback I do this:
if self.downloadCompleted {
self.downloadCompleted(book)
}
The compiler complains with this error message:
Type '(MLBook) -> (Void)!' does not conform to protocol 'BooleanType'
If I remove the if statement the compiler says:
Property 'self.downloadCompleted' not initialized
even though it's implicitly unwrapped.
When I try to get the callback:
BookStore.sharedInstance.downloadCompleted{(book: MLBook) -> () in
println("Print if you got the callback")
}
I get this error message:
'(MLBook) -> ()' is not convertible to 'MLBook'
I'm more worried about the last error message as I'm not quite sure what it is trying to tell me.
Any help would be appreciated. Thanks
Upvotes: 6
Views: 12302
Reputation: 70235
Here is your working example. You have a number of mistakes which the attached illustrates. Note
I had the download()
method return Bool
so that the result can be see in this screen shot.
But, your use of an implicitly unwrapped optional (aka '!') is incorrect. Such an optional is used when the value may be nil
but will be assigned at a known time and not changed (see Apple documentation for a description). Your downloadCompleted
is a true optional (at least in your example use). Thus, better code, which turns out to be slightly simpler is:
Upvotes: 9
Reputation: 8937
2 mistakes. 1st, The whole type should be wrapped in (), then followed a ? or ! as a optional or implicit unwrapped optional. 2nd, you should check with nil, in swift, no implicit boolean conversion.
In your use case, you should use Optional instead of Implicit unwrapped. Because there is big chance that your property has a nil value. With IUO(Implicit unwrapped optional), you skip compiler warning and will get a runtime error.
import Foundation
class MLBook {
var name = "name"
}
class A {
var downloadCompleted: ((MLBook) -> Void)?
func down(){
var book = MLBook()
if let cb = self.downloadCompleted {
cb(book)
}
}
}
var a = A()
a.downloadCompleted = {
(book: MLBook) -> Void in
println(book.name)
}
a.down()
Upvotes: 5