14

Having a hard time figuring out how to properly declare/use blocks with swift. What would be the swift equivalent of the following code?

Thanks.

^(PFUser *user, NSError *error) {
if (!user) {
    NSLog(@"Uh oh. The user cancelled the Facebook login.");
} else if (user.isNew) {
    NSLog(@"User signed up and logged in through Facebook!");
} else {
    NSLog(@"User logged in through Facebook!");
}
1

6 Answers 6

15

The equivalent of Objective-C blocks are swift closures, so it would go as follows

{ (user: PFUser, error: NSError) in
  if (!user) {
    println("Uh oh. The user cancelled the Facebook login.");
  } else if (user.isNew) {
    println("User signed up and logged in through Facebook!");
  } else {
    println("User logged in through Facebook!");
  }
}
Sign up to request clarification or add additional context in comments.

Comments

7

You have many ways offered to pass a block equivalent to function in Swift.

I found three.

To understand this I suggest you to test in playground this little piece of code.

func test(function:String -> String) -> String
{
    return function("test")
}

func funcStyle(s:String) -> String
{
    return "FUNC__" + s + "__FUNC"
}
let resultFunc = test(funcStyle)

let blockStyle:(String) -> String = {s in return "BLOCK__" + s + "__BLOCK"}
let resultBlock = test(blockStyle)

let resultAnon = test({(s:String) -> String in return "ANON_" + s + "__ANON" })


println(resultFunc)
println(resultBlock)
println(resultAnon)

Update: There are 2 special cases to the Anonymous function.

The first is that function signature can be inferred so you don't have to rewrite it.

let resultShortAnon = test({return "ANON_" + $0 + "__ANON" })

The second special case works only if the block is the last argument, it's called trailing closure

Here is an example (merged with inferred signature to show Swift power)

let resultTrailingClosure = test { return "TRAILCLOS_" + $0 + "__TRAILCLOS" }

Finally:

Using all this power what I'd do is mixing trailing closure and type inference (with naming for readability)

PFFacebookUtils.logInWithPermissions(permissions) {
    user, error in
    if (!user) {
        println("Uh oh. The user cancelled the Facebook login.")
    } else if (user.isNew) {
        println("User signed up and logged in through Facebook!")
    } else {
        println("User logged in through Facebook!")
    }
}

IMO it's more beautiful than in ObjC

3 Comments

Hey @Fran .. you may be able to provide a more up-to-date answer to THIS question ... stackoverflow.com/a/20760583/294884 thanks! you're pretty much it for "expert in SWIFT blocks..." :)
Thanks you. I'll send this answer just for information even if the question is for objC.
...and IMHO, if you'd used the __FUNCTION__ that would have been more beautiful.
2

See if this works for you. It's crazy trying to learn this on day two.

let afterSignInAttempt: (PFUser?, NSError) -> Void = { user, error in
    if(!user){
      NSLog("Uh oh.")
    } else {
      user.isNew ? NSLog("Signed up") : NSLog("User Logged in")
    }
}

Comments

2

Critically, if user can be nil then it must be declared as an Optional. Thus:

{ (user: PFUser?, error: NSError) -> {} in
         if (nil == user) ...
    }

noting that the type for user includes ? to indicate that user is an optional argument (either nil or of type PFUser).

Other answers, that don't use an Optional, won't even compile.

Comments

2

If you want to store block in a variable and call it later, check this answer

Comments

0

// define it

class IDDBlockTime {
    // return time elapsed in milliseconds
    //
    static func timeSpent(_ block: (Void) -> Void) -> TimeInterval {
        let methodStart = Date()

        block()
        return Date().timeIntervalSince(methodStart) * 1000.0
    }
}

// use it

    let timeSpent = IDDBlockTime.timeSpent {
        // lines of code you want to measure
        //
        self.doSomethig()
    }

    print("timeSpent: '\(timeSpent) ms'")

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.