如何使用Swift在api响应中等待登录视图的值

时间:2019-06-05 08:43:22

标签: ios api

我开始学习Swift,并不熟悉Swift代码的同步和异步操作。 我想在我的登录视图(viewcontroller)中,当用户输入ID,PASSWORD,然后从API请求服务时,API将比较数据库数据是否正确,如果正确返回json data => true,错误返回json数据=>假

在获得API响应后,我不知道如何执行我的login()。

我研究了很多有关此的信息,包括NSOperationQueue ...等。

但是实施的最终结果失败了,请有经验的人帮助我,谢谢!

var jsonmessage: Bool? = nil

当onclickLogin使用segue转到下一页

 @IBAction func onclickLogin(_ sender: Any) {

            Postusercheck()
            login()
}

请求api

 func Postusercheck(){
        let parameters = ["ID":txtcount.text,"Password":txtpaswoerd.text] //post request with id,password
        print(parameters)
        let url = URL(string: "http://" + apiip + "/api/user")! //change the url
        let session = URLSession.shared
        //now create the URLRequest object using the url object
        var request = URLRequest(url: url)
        request.httpMethod = "POST" //set http method as POST
        do {
            request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted) // pass
        } catch let error {
            print(error.localizedDescription)
        }
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        request.addValue("application/json", forHTTPHeaderField: "Accept")
        let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in
            guard error == nil else {
                return
            }
            guard let data = data else {
                return
            }
            do {
                if let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] {
                    print(json)
                    self.jsonmessage = json["message"] as? Bool
                    print("Title: \(String(describing:  self.abc)))")
                    }
                } catch let error {
                print(error.localizedDescription)
                                  }
        })
                task.resume()
    }
 func login(){

    if (self.jsonmessage == true){
    }
    else if txtcount.text == "" || txtpaswoerd.text == "" {
    let alert = UIAlertController(title: "Don't empty the field", message: "Please enter again", preferredStyle: .alert)
    let ok = UIAlertAction(title: "OK", style: .default, handler: nil)

    alert.addAction(ok)
    present(alert, animated: true, completion: nil)

        }
        else
            {
                let alert = UIAlertController(title: "ID OR PASSWORD ERROR", message: "Please enter again", preferredStyle: .alert)
                let ok = UIAlertAction(title: "OK", style: .default, handler: nil)
                alert.addAction(ok)
                present(alert, animated: true, completion: nil)
            }
    }

========================更新================

@IBAction func onclickLogin(_ sender: Any) {

        Postusercheck()
}

    func Postusercheck(){

        let parameters = ["ID":txtcount.text,"Password":txtpaswoerd.text] //post request with id,password
        print(parameters)
        let url = URL(string: "http://" + apiip + "/api/user")! //change the url
        let session = URLSession.shared
        //now create the URLRequest object using the url object
        var request = URLRequest(url: url)
        request.httpMethod = "POST" //set http method as POST
        do {
            request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted) // pass
        } catch let error {
            print(error.localizedDescription)
        }
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        request.addValue("application/json", forHTTPHeaderField: "Accept")
        let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in
            guard error == nil else {
                return
            }
            guard let data = data else {
                return
            }
            do {
                if let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] {
                    print(json)
                    self.jsonmessage = json["message"] as? Bool
                    self.login()

                    }
                } catch let error {
                print(error.localizedDescription)
                                  }
        })
                task.resume()
    }
func login(){
    if (self.jsonmessage == true){
        //Navigate to the another view controller
        let mainStoryboard = UIStoryboard.init(name: "Main", bundle: nil)
        let anotherViewController = mainStoryboard.instantiateViewController(withIdentifier: "AnotherViewController")
        self.navigationController?.pushViewController(anotherViewController, animated: true)
    }
    else if txtcount.text == "" || txtpaswoerd.text == "" {
        let alert = UIAlertController(title: "Don't empty the field", message: "Please enter again", preferredStyle: .alert)
        let ok = UIAlertAction(title: "OK", style: .default, handler: nil)

        alert.addAction(ok)
        present(alert, animated: true, completion: nil)
    }
    else
    {
        let alert = UIAlertController(title: "ID OR PASSWORD ERROR", message: "Please enter again", preferredStyle: .alert)
        let ok = UIAlertAction(title: "OK", style: .default, handler: nil)
        alert.addAction(ok)
        present(alert, animated: true, completion: nil)
    }
}

当我尝试新代码时。

我已取消原始的segue连接。我在想要的页面上将Storboard ID设置为AnotherViewController,但是成功验证了帐户密码后,他不会进入下一页。

他刚在原始页面停留(帐户密码验证成功后) 如果我输入了错误的帐户密码,它仍然会收到错误消息。此功能很有用。

1 个答案:

答案 0 :(得分:0)

在URLSession的完成处理程序中进行函数调用,如下所示:

    let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in
                guard error == nil else {
                    return
                }
                guard let data = data else {
                    return
                }
                do {
                    if let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] {
                        print(json)
                        self.jsonmessage = json["message"] as? Bool
                        self.login()
                        print("Title: \(String(describing:  self.abc)))")
                        }
                    } catch let error {
                    print(error.localizedDescription)
                                      }
            })

当您调用Postusercheck时,必须从按钮的IBAction原因中删除登录调用,它将进行Web服务调用,并且由于session.dataTask是异步的,因此它将不等待响应。因此,执行将返回到IBAction,并且将调用login(),尽管您尚未收到Web服务响应,并且您不知道用户名和密码是否正确。因此,您必须从这样的按钮单击操作中删除登录呼叫:

@IBAction func onclickLogin(_ sender: Any) {

            Postusercheck()
}

如下更改登录功能:

func login(){

    if (self.jsonmessage == true){
       //Navigate to the another view controller
       let mainStoryboard = UIStoryboard.init(name: "Main", bundle: nil)
       let anotherViewController = mainStoryboard.instantiateViewController(withIdentifier: "AnotherViewController")
       self.navigationController?.pushViewController(anotherViewController, animated: true)    
    }
    else if txtcount.text == "" || txtpaswoerd.text == "" {
    let alert = UIAlertController(title: "Don't empty the field", message: "Please enter again", preferredStyle: .alert)
    let ok = UIAlertAction(title: "OK", style: .default, handler: nil)

    alert.addAction(ok)
    present(alert, animated: true, completion: nil)

        }
        else
            {
                let alert = UIAlertController(title: "ID OR PASSWORD ERROR", message: "Please enter again", preferredStyle: .alert)
                let ok = UIAlertAction(title: "OK", style: .default, handler: nil)
                alert.addAction(ok)
                present(alert, animated: true, completion: nil)
            }
    }

请确保在故事板中有一个名为“ Main”的视图控制器,并且故事板ID为“ AnotherViewController”,否则它将无法正常工作。

另一个导航选项是通过情节提要中的segues。下面是一个很好的教程,可以学习有关故事板的精彩内容。

https://www.raywenderlich.com/464-storyboards-tutorial-for-ios-part-1

还有一件事是,Postusercheck()不是很好的函数名。请参阅以下准则,了解swift广泛使用的命名约定中的最佳做法:

https://github.com/raywenderlich/swift-style-guide