I would like to create a function that uses generic closure (block) in swift.
My first attempt was to do like :
func saveWithCompletionObject(obj : AnyObject, success : AnyObject -> Void, failure : Void -> Void)
But as soon as I call this function with another block, such as :
func doSomething(success : String -> Void, failure : Void -> Void)
{
saveWithCompletionObject("Example", success, failure)
}
I get an error : 'AnyObject' is not a subtype of 'String'
Thanks in advance !
You cannot pass a closure of type String->Void
to a parameter of type AnyObject->Void
.
However, you can define a generic function:
func saveWithCompletionObject<T>(obj : T, success : T -> Void, failure : Void -> Void) {
// ...
success(obj)
}
Now the compiler can verify that obj
has the same type
as the parameter of success
, for example:
func doSomething(success : String -> Void, failure : Void -> Void)
{
saveWithCompletionObject("Example", success, failure)
}
func doSomethingElse(success : Int -> Void, failure : Void -> Void)
{
saveWithCompletionObject(13, success, failure)
}
But I would recommend that saveWithCompletionObject
just takes a Void->Void
parameter (without generics):
func saveWithCompletionObject(success : Void -> Void, failure : Void -> Void) {
// ...
success()
}
and the caller wraps its closure:
func doSomething(success : String -> Void, failure : Void -> Void)
{
saveWithCompletionObject( { success("Example") } , failure)
}
func doSomethingElse(success : Int -> Void, failure : Void -> Void)
{
saveWithCompletionObject( { success(13) }, failure)
}
This is more flexible, e.g. for callback functions with more than one parameter:
func andNowForSomethingCompletelyDifferent(success : (Int, Double) -> Void, failure : Void -> Void)
{
saveWithCompletionObject( { success(13, M_PI) }, failure)
}