快速执行segue 4 [英] perform segue swift 4

查看:58
本文介绍了快速执行segue 4的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试用我的数据库验证用户的登录名.当按下登录按钮时,我想根据数据库返回的信息说是否会发生segue.我首先将可变决策最初设置为true,如果无法验证用户,则希望将其设置为false并防止segue.这是我的代码,但是有问题.最后的return语句始终为true.基本上发生的是在从数据库返回响应之前,首先调用.resume()之后的最后一个return语句.有人可以弄清楚为什么会这样吗

I am trying to validate the login of a user with my database. When the login button is pressed I want to say whether a segue will happen or no based on the info returned back from the database. I start with a variable decision set to true initially and if the I can't validate the user I want to set it to false and prevent segue. This is the code that I have, but there is a problem with it. The return statement at the end is always true. What happens basically is the return statement at the end after .resume() get called first before the response is returned from the database. Can someone clarify why this is happening

 override func shouldPerformSegue(withIdentifier identifier: String,sender: 
 Any?) -> Bool
 {
             var decision = true
            let url = URL(string:"http://192.23.25.98/login/php")
            var request = URLRequest(url: url!)
            request.httpMethod = "POST"
            let body = "UserNameLogIn=\(userName.text!.lowercased())&PasswordLogIn=\(passWord.text!.lowercased())"
            request.httpBody=body.data(using: String.Encoding.utf8)
            URLSession.shared.dataTask(with: request) { (data:Data?, response:URLResponse?, error:Error?) in
                if (error == nil)
               {
                    DispatchQueue.main.async(execute: {
                        do
                        {
                            let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? Dictionary<AnyHashable,AnyObject>
                            guard let parseJson = json else{
                                print ("error parsing")
                                return
                            }
                            let status = parseJson["status"]
                            if (status != nil)
                            {
                                if (parseJson.count>3)
                                {
                                    decision = true

                                }
                                else
                                {
                                    decision = false


                                }
                            }
                        }
                        catch
                        {

                            print("error: \(error)")
                        }
                    })
                }
                else
                {
                    decision = false
                }
                }.resume()
    return decision
}

推荐答案

您无需在按钮上轻按即可启动segue并尝试捕获shouldPerformSegue(withIdentifier:sender:)中的异步过程,而应该在按钮上定义一个@IBAction执行验证请求,并以编程方式启动成功(如果成功).

Rather than initiating the segue on the tap of the button and trying to capture an asynchronous process within shouldPerformSegue(withIdentifier:sender:), you instead should just have the button define a @IBAction that performs the validation request and programmatically initiates the segue if it succeeded.

因此:

  1. 从按钮中删除标记.

  1. Remove the segue from the button.

通过 control (从第一个场景上方的栏中的视图控制器图标拖动到第二个场景)来在视图控制器之间添加序列:

Add segue between the view controllers by control-dragging from the view controller icon in the bar above the first scene to the second scene:

选择序列,并在属性检查器中为其命名:

Select the segue and give it a name in the attributes inspector:

已从按钮上删除了序列,现在可以将按钮连接到@IBAction方法:

Having removed the segue from the button, you can now hook up your button to an @IBAction method:

您的登录操作应 performSegue(withIdentifier:sender:) 您完成了验证逻辑:

Your login action should performSegue(withIdentifier:sender:) when you finish your validation logic:

performSegue(withIdentifier: "NextSceneSegue", sender: self)

例如

@IBAction func didTapLoginButton(_ sender: Any) {
    let url = URL(string:"http://192.23.25.98/login/php")
    var request = URLRequest(url: url!)
    request.httpMethod = "POST"
    request.httpBody = ["UserNameLogIn": useridTextField.text!, "PasswordLogIn": passwordTextField.text!]
        .map { $0.key + "=" + $0.value.addingPercentEncoding(withAllowedCharacters: .urlQueryValueAllowed)! }
        .joined(separator: "&")
        .data(using: .utf8)

    URLSession.shared.dataTask(with: request) { data, response, error in
        DispatchQueue.main.async {
            guard let data = data, let httpResponse = response as? HTTPURLResponse, (200 ..< 300) ~= httpResponse.statusCode, error == nil else {
                // handle basic network errors here
                return
            }

            guard let json = (try? JSONSerialization.jsonObject(with: data)) as? [String: Any] else {
                // handle json parsing errors here
                return
            }

            if json["status"] == nil  {
                // handle missing status here
                return
            }

            guard json.count > 3 else {
                // handle incorrect count here
                return
            }

            self.performSegue(withIdentifier: "NextSceneSegue", sender: self)
        }
    }.resume()
}

  • 注意,我对请求正文中的值进行了百分比编码.特别是密码可能包含保留字符.而且我不会犯使用 .urlQueryAllowed 的错误,但改为使用.urlQueryValueAllowed,在其中我提取了一些保留字符:

  • Note, I percent encode the values in the body of the request. Passwords, in particular, might contain reserved characters. And I don't make the mistake of using .urlQueryAllowed, but instead used .urlQueryValueAllowed, in which I pulled out a few reserved characters:

    extension CharacterSet {
    
        /// Returns the character set for characters allowed in the individual parameters within a query URL component.
        ///
        /// The query component of a URL is the component immediately following a question mark (?).
        /// For example, in the URL `http://www.example.com/index.php?key1=value1#jumpLink`, the query
        /// component is `key1=value1`. The individual parameters of that query would be the key `key1`
        /// and its associated value `value1`.
        ///
        /// According to RFC 3986, the set of unreserved characters includes
        ///
        /// `ALPHA / DIGIT / "-" / "." / "_" / "~"`
        ///
        /// In section 3.4 of the RFC, it further recommends adding `/` and `?` to the list of unescaped characters
        /// for the sake of compatibility with some erroneous implementations, so this routine also allows those
        /// to pass unescaped.
    
        static var urlQueryValueAllowed: CharacterSet = {
            let generalDelimitersToEncode = ":#[]@"    // does not include "?" or "/" due to RFC 3986 - Section 3.4
            let subDelimitersToEncode = "!$&'()*+,;="
    
            var allowed = CharacterSet.urlQueryAllowed
            allowed.remove(charactersIn: generalDelimitersToEncode + subDelimitersToEncode)
            return allowed
        }()
    
    }
    

  • 这篇关于快速执行segue 4的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆