执行segue swift 4

时间:2018-05-18 05:40:07

标签: json swift post segue

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

 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
}

1 个答案:

答案 0 :(得分:1)

而不是在点击按钮时启动segue并尝试捕获shouldPerformSegue(withIdentifier:sender:)内的异步进程,而是应该让按钮定义执行验证请求的@IBAction并以编程方式启动如果它成功了。

因此:

  1. 从按钮中删除segue。

  2. 通过 control 在视图控制器之间添加segue - 从第一个场景上方的条形图中的视图控制器图标拖拽到第二个场景:

    enter image description here

  3. 选择segue并在属性检查器中为其命名:

    enter image description here

  4. 从按钮中移除了segue后,您现在可以将按钮连接到@IBAction方法:

    enter image description here

  5. 完成验证逻辑后,您的登录操作应为performSegue(withIdentifier:sender:)

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

    E.g。

    @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()
    }
    
  6. 注意,我百分比编码请求正文中的值。特别是密码可能包含保留字符。我没有犯错误使用.urlQueryAllowed,而是使用了.urlQueryValueAllowed,其中我提取了一些保留字符:

    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
        }()
    
    }