5

I am trying to use Parse written with Swift. I am able to log in without any trouble but I am struggling with telling my app that the user is logged in.

I am using logInWithUsernameInBackground and I simply want to return a boolean if the log in succeeded.

When I use:

func authenticateUser() -> Bool{
    PFUser.logInWithUsernameInBackground(userName.text, password: passwordField.text, block: {
        (user,error) in
        return error === nil
    })
}

I get the error "Bool is not convertible to Void" which makes sense.

So if I change line 3 to read:

(user,error) -> Bool in

I end up with the error "Missing argument for parameter selector in call"

However, This method doesn't require a selector parameter.

So where am I going wrong? How do I return a bool based on whether or not there was an error at log in?

AppDever
  • 687
  • 1
  • 7
  • 17
  • On a side note, this code works perfectly fine: var error:NSError? PFUser.logInWithUsername(userName.text, password: passwordField.text, error: &error) if(error == nil){ return true }else{ return false } But the console has this warning: Warning: A long-running operation is being executed on the main thread. – AppDever Dec 03 '14 at 05:51
  • 1
    You'll have to understand that logInWithUsernameInBackground is an *asynchronous* method, and that your authenticateUser method returns *before* the completion closure has been called. – Martin R Dec 03 '14 at 06:15

1 Answers1

11

Based on the code as you wrote it, if you wanted to return Bool, you'd do this:

func authenticateUser() -> Bool{
    PFUser.logInWithUsernameInBackground(userName.text, password: passwordField.text, block: {
        (user,error) in
        return error === nil
    })

    return true // This is where the bool is returned
}

However, what you want to do, based on your code, is:

func authenticateUser(completion:(Bool) -> ()) {
    PFUser.logInWithUsernameInBackground(userName.text, password: passwordField.text, block: {
        (user,error) in
        completion(error === nil)
    })
}

You can invoke the call by one of the following:

authenticateUser(){
    result in
    if result {
        println("Authenticated")
    } else {
        println("Not authenticated")
    }
}

or

authenticateUser({
  result in
    if result {
        println("Authenticated")
    } else {
        println("Not authenticated")
    }
})

The first one is shorthand and is more convenient when you have other arguments prior to the closure.

This implies that you are getting back your Bool for as to whether or not you authenticated asynchronously.

BTW, you really only need to do error == nil

Mobile Ben
  • 7,121
  • 1
  • 27
  • 43
  • That's exactly what I want. One thing, how do I call this? What parameter do I pass it? ... if self.authenticateUser() { //Missing argument for parameter #1 in call ... Also: I know that is where a return would go but that would always be true which is not what I want so thank you for correcting it with the updated code ... The === was to mute an error – AppDever Dec 04 '14 at 03:17