iOS : Swift : Blocks = Closures

Closure on closures
Closure on closures

I’ve never really liked blocks in ObjC.

When Swift came out it made things more complicated for me because I’ve never really liked C either.

Finally when I had to deal with closures in Swift, well that’s just gonna piss a lot of people off!

After a few days reviewing tons of material online, and I mean TONS!  I came to understand this:

The only C-like exposure I had prior to ObjC was a little PHP.  So that allows me to understand a function, which is the equivalent of a method in ObjC:

DECLARING

func sayHello( ) {

     println(“Hello World”)

}

CALLING

sayHello( )

RESULT

Hello World

Even if you didn’t have any exposure to C or PHP or some other “not-so-friendly” language as ObjC, you can surely understand that

  1. The function is called sayHello
  2. That it takes no input-parameters because the ( ) is empty
  3. That it has no return type because it returns nothing since its missing the keyword “return” inside of it 🙂
  4. And that all it does, instead of returning a value, is print out Hello World

Just to clarify, let’s look at a function with a return value:

DECLARING

func sayHello () -> String {

    var result = “Hello World”

    return result

}

CALLING

var whoAreYou = sayHello()

RESULT (value of whoAreYou)

Hello World

As you can see here, we actually return a value from this function, which we can assign to a variable.  I had to assign it to a variable so that it made sense to actually return a value from a function.  

So we added an output-value to an otherwise plain vanilla function.  Now lets go for the next kind of function, plain + output + input:

DECLARING

func sayHello (friendOne:String) -> String {

    println(“Hi \(friendOne)”)

    var result = “Hello, ” + friendOne

    return result

}

CALLING

var whoAreYou = sayHello(“Marcio”)

RESULT (value of whoAreYou)

Hello, Marcio

Great!  So you’ve got functions covered:

  • Plain void functions
  • Returning output-value functions
  • Input-Paramter, returning output-value functions

CLOSURES (or blocks from ObjC)

There really is no simple way to explain it in a few words.  But the first thing that stands out from a closure or block, is that IT IS a function, yes!  But it can be passed around like a variable.  So let’s take a look:

var someVariable: String

There, we just declared a variable of type string.  Let’s declare another variable:

var someOtherVariable: ( ) -> ( ) = { }

There, we have just declared another variable, of type…? :s

Simply combine the concepts:

variable = function

And we know that a function is:

function = functionName (input-parameter) -> (Output-value) {some code}

So now say:

variable = function = functionName (input-parameter) -> (Output-value) {some code}

Now drop the middle “function” 🙂

variable = functionName (input-parameter) -> (Output-value) {some code}

If you don’t want the function to have a name, because you are assigning it to a variable anyway, so you can just call it by calling the variable:

variable = (input-parameter) -> (Output-value) {some code}

Hey, that looks a lot like what we had above:

var someOtherVariable: ( ) -> ( ) = { }

Cool!  So what does it all mean Basil?

The important thing is that you will use closures in Swift.  I was working with Parse SDK the other day and I ran into this in Xcode:

Get closure on Closures
Get closure on Closures

This is the first stage of Autocomplete which you may already be familiar with.  It’s telling you this:

Void saveInBackgroundWithBlock(block: PFBooleanResultBlock!(Bool, NSError!) -> Void)

You already know what this means, its just a function/method that takes a block as a parameter.  

This function returns Void, according to the left Void in that line.  

Let’s say that the method is called saveInBackgroundWithBlock ( X ) and it takes 1 parameter, X, where X is a block.

The block is defined as a variable “block:” and its called PFBooleanResultBlock!

It has 2 output-values Bool & NSError.

Now you know how to fill it in.  But wait, there’s more…if you call in the next 15 minutes 🙂

But seriously, Xcode now has something new.  Check it out!  To select that method in the image above, you hit Enter.  This spits out the method signature in the Editor window and expects you to fill in the rest…THE NERVE!  Luckily, you can hit Enter again while that blue selection is highlighting the block and that will give you this:

tah dah!

Get closure on Closures
Get closure on Closures

Now that’s better!  This is Xcode’s new second stage Autocomplete.  Its telling us that the block is defined by { } and it takes 2 input-parameters and returns a Void.  That new “in” keyword serves to separate the return (which is in this case, Void) from the actual code block which follows.

So you can call closures like so:

object.saveInBackgroundWithBlock {succeeded, error in

//some code

}

OR

object.saveInBackgroundWithBlock { (succeeded, error) -> Void in

//some code

}

 OR

object.saveInBackgroundWithBlock( { (succeeded:Bool, error:NSError!) in

//some code

})

OR

object.saveInBackground( { (succeeded:Bool, error:NSError! ) -> Void in } )

OR you can assign it:

var someVar: () -> () = {              

println(“Hello World”)

}

Enjoy!

 

EDIT: In brief:

How to write or declare closures:

{ (succeeded: Bool, error: NSError?) -> Void in /* code */ }
{ (succeeded: Bool, error: NSError?) in /* code */ }
{ (succeeded, error) in /* code */ }
{ succeeded, error in /* code */ }
{ /* code using $0 for succeeded and $1 for error */ }

How to pass a closure:

object.saveInBackgroundWithBlock({ /* closure */ })
object.saveInBackgroundWithBlock() { /* closure */ }   // Only if closure is last arg
object.saveInBackgroundWithBlock { /* closure */ }     // Only if closure is only arg
Advertisements

3 thoughts on “iOS : Swift : Blocks = Closures

  1. Thanks for sharing your revelation. I’m a Parse.com neophyte encountering the SAME saveinbackground()… closure when I just happened upon your article. Thanks again!

  2. finally, a geek that can articulate complexity with just the right touch of folksiness.

    would love a lesson on protocols and delegation.

    best

    😉

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s