简体   繁体   中英

should perform segue with identifier - Error

I am using shouldPerformSegueWithIdentifier method control when to perform the segue.

  override func shouldPerformSegueWithIdentifier(identifier: String!, sender: AnyObject?) -> Bool {

    if identifier == "login" {
        if loginSuccess != true {

            var alert = UIAlertController(title: "Alert", message: "Please enter correct login details", preferredStyle: UIAlertControllerStyle.Alert)
            alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: nil))
            self.presentViewController(alert, animated: true, completion: nil)

            return false
        }
    }

    return true
}

I have declared the loginSuccess variable in the very beginning of the class like so:

   var loginSuccess:Bool? 

And I change this boolean variable to true when the API successfully authenticates the users login details in the following way:

  self.loginSuccess = true

The above line is placed after the if-statement that checks that the JSON being returned by the API is not empty.

My issue is that when I run the code and enter my login details within the app and click on the login button, it always rejects the login details the first time and when I click the login button the 2nd time it performs the segue. No matter if my login details are perfect, the first click is always rejected and the 2nd is accepted the segue is processed.

I think when it first runs the segue code it sees the initial value of "loginSuccess" as false and thats why it rejects it.

How can I solve this issue. It has something to do with the boolean variable.

The Complete Code:

 import UIKit

 class ViewController: UIViewController {

 var loginSuccess:Bool?

@IBOutlet weak var password: UITextField!
@IBOutlet weak var emailAdd: UITextField!


@IBAction func loginUser(sender: AnyObject) {

    var x:String = password.text
    var y:String = emailAdd.text

    var request = NSMutableURLRequest(URL: NSURL(string: "http://myAPIlink.com/login")!)
    var session = NSURLSession.sharedSession()
    request.HTTPMethod = "POST"

    var params = ["email":"\(y)", "password":"\(x)"] as Dictionary<String, String>

    var err: NSError?
    request.HTTPBody = NSJSONSerialization.dataWithJSONObject(params, options: nil, error: &err)
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    request.addValue("application/json", forHTTPHeaderField: "Accept")

    var task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
        println("Response: \(response)")
        var strData = NSString(data: data, encoding: NSUTF8StringEncoding)
        println("Body: \(strData)")
        var err: NSError?
        var json = NSJSONSerialization.JSONObjectWithData(data, options: .MutableLeaves, error: &err) as? NSDictionary

        // Did the JSONObjectWithData constructor return an error? If so, log the error to the console
        if(err != nil) {

            println(err!.localizedDescription)
            let jsonStr = NSString(data: data, encoding: NSUTF8StringEncoding)
            println("Error could not parse JSON: '\(jsonStr)'")

        }
        else {

            // The JSONObjectWithData constructor didn't return an error. But, we should still
            // check and make sure that json has a value using optional binding.

            if let parseJSON = json {

                // CHANGE THE loginSuccess Boolean HERE
                    self.loginSuccess = true

                // Okay, the parsedJSON is here, let's get the value for 'success' out of it

                var fullname = parseJSON["fullname"] as! String
                println("Succes: \(fullname)")

                var region = parseJSON["region"] as! String
                println("Region: \(region)")

                var uTarget = parseJSON["target"] as! String
                println("Target: \(uTarget)")


            }
            else {
                // Woa, okay the json object was nil, something went worng. Maybe the server isn't running?
                let jsonStr = NSString(data: data, encoding: NSUTF8StringEncoding)
                println("Error could not parse JSON: \(jsonStr)")

            }
        }
    })

    task.resume()
}
override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    self.view.backgroundColor = UIColor(patternImage: UIImage(named: "podcastbg.jpg")!)

}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}



override func shouldPerformSegueWithIdentifier(identifier: String!, sender: AnyObject?) -> Bool {

    if identifier == "login" {
        if loginSuccess != true {

            var alert = UIAlertController(title: "Alert", message: "Please enter correct login details", preferredStyle: UIAlertControllerStyle.Alert)
            alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: nil))
            self.presentViewController(alert, animated: true, completion: nil)

            return false
        }
    }

    return true
}
}

If you need more information to answer the question please let me know. Thanks in advance.

Post your login button code.

It sounds like your login process is asynchronous and you aren't waiting until it completes before you trigger the segue. You need to write it to use a completion block.

It sounds to me like a bad design.

Edit:

What you are doing will not work.

Remove the segue from the login button.

Add code in your loginUser method, inside the completion handler, that invokes your segue on the main thread once login is complete.

I would change your Code a little bit:

  1. User should enter Username and Passwort
  2. Make an (async) call to your service (show the user a spinner)
  3. If the result is valid -> change the segue

I would not use

shouldPerformSegueWithIdentifier

Just:

  if let parseJSON = json {

            // CHANGE THE loginSuccess Boolean HERE

            self.performSegueWithIdentifier("loginSuccessSegue", sender: nil)

Or otherwise show the User an Error Message.

If you want you can set a "Loginsuccess" value, and check with

   prepareForSegue

我看不到在您的登录按钮代码中应该在哪里shouldPerformSegueWithIdentifier

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM