0

我在 User 类中有以下函数:

// Attempts to log in the user, given a password.
// Sets user's loginSuccessful to true upon successful login, false otherwise.
// If failed login, user's loginFailedMessage is also updated.
func attemptLogin(password:String) {
    // create a new NSURL pointing to the PHP login script
    let url = NSURL(string: loginScriptLocation)

    // create a new NSMutableURLRequest of type POST
    let request = NSMutableURLRequest(URL: url!)
    request.HTTPMethod = "POST"

    // add POST string with username and password to request
    let postString = "username=\(self.username)&password=\(password)"
    request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)

    // send the request and get the JSON results
    let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
        data, response, error in
        // if there is an error with the request, print it
        if error != nil {
            println("error: \(error)")
            return
        }
        // otherwise, go ahead and parse JSON results
        var err:NSError?
        var json = NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers, error: &err) as? NSDictionary
        if let parseJSON = json {
            var resultValue = parseJSON["status"] as? String
            if resultValue! == "success" {
                // login successful
                self.loginSuccessful = true
            }
            else {
                // login not successful
                self.loginSuccessful = false
                self.loginFailedMessage = parseJSON["message"] as! String
            }
        }
    }
    task.resume()
}

问题是...

当我的登录 UIButton 的 IBAction 被触发时,在我的 LoginViewController 中调用此尝试登录()函数。在此 IBAction 函数内调用了尝试登录()后,它后面的语句检查用户的 loginSuccessful 变量是否已设置为 true。如果为真,则意味着切换到不同的视图控制器(登录用户);如果为 false,则表示显示错误消息。

但当然这不起作用,因为当我检查 loginSuccessful 是否已设置为 true 时(在我调用尝试登录()之后),我的 NSURLSession 还没有达到这一点。我觉得我需要在我的 NSURLSession 中添加一个“关闭”或“完成处理程序”,但即使在搜索 StackOverflow 以获取示例之后,我也真的不明白如何做到这一点。我是 iOS 编程和异步/同步方法的初学者,所以不要评判我!

如何修改现有的尝试登录()函数,以便在 NSURLSession 完成时触发某些事情(这样我可以在视图控制器中转到另一个屏幕或在出现错误时向用户显示警报)?

这是我的 LoginViewController 中的代码:

// Triggered when login button is tapped
// Attempts to log in a user with username and password typed in.
// Successful login -> takes user to Explore screen
// Failed login -> shows alert message with error
@IBAction func loginButtonTap(sender: UIButton) {
    if (usernameTextField.text.isEmpty || passwordTextField.text.isEmpty) {
        // show alert saying missing required field
    }
    else {
        // attempt login
        self.myUser.setUsernameWithoutPushingToDatabase(self.usernameTextField.text)
        self.myUser.attemptLogin(self.passwordTextField.text)
        if (self.myUser.didLoginSuccessfully()) {
            // login successful, segue to Explore screen
            self.performSegueWithIdentifier("loginToExploreSegue", sender: self)
        }
        else {
            // login failed, display alert with error message
            var incorrectPassAlert = UIAlertController(title: "Login Failed", message: self.myUser.loginFailedMessage, preferredStyle: UIAlertControllerStyle.Alert)
            incorrectPassAlert.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
            self.presentViewController(incorrectPassAlert, animated: true, completion: nil)
        }
    }
}
4

2 回答 2

1

您是对的,您希望将闭包传递给attemptLogin

尝试这样的事情

func attemptLogin(password:String, completion: (Bool) -> Void)

然后

if resultValue! == "success" {
    // login successful
    completion(true)
}
else {
    completion(false)
}

最后你必须在loginButtonTap

self.myUser.attemptLogin(self.passwordTextField.text, completion: (successful: Bool) -> Void) { 
   if successful {
        // login was good
   } else {
       // login was bad
   }
})
于 2015-06-23T19:31:58.570 回答
1

您的 attempLogin 函数应采用如下完成处理程序:

func attemptLogin(password:String, completionHandler: (success: Bool, message: String) -> ()) { your code }

在该方法中,您应该将结果数据传递给该完成处理程序:

if resultValue! == "success" {
      // login successful
      self.loginSuccessful = true
      completionHandler(success: True, message: "Login Successful.")
}
else {
      // login not successful
      self.loginSuccessful = false
      self.loginFailedMessage = parseJSON["message"] as! String
      completionHandler(success: False, message: loginFailedMessage)
}

最后,您可以像这样调用 attempLogin:

self.myUser.attemptLogin(self.passwordTextField.text, {(success: Bool, message: String) -> () in
         if(success) {
        //do something
         }
         else {
        // do something or print message etc.
        }
    })
于 2015-06-23T19:35:00.117 回答