json - 执行 segue swift 4
问题描述
我正在尝试使用我的数据库验证用户的登录。当按下登录按钮时,我想根据从数据库返回的信息来判断是否会发生转场。我从最初设置为 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
}
解决方案
与其在点击按钮时启动 segue 并尝试在 中捕获异步过程,不如shouldPerformSegue(withIdentifier:sender:)
让按钮定义一个@IBAction
执行验证请求并在成功时以编程方式启动 segue。
因此:
从按钮中删除 segue。
control通过从第一个场景上方栏中的视图控制器图标拖动到第二个场景,在视图控制器之间添加 segue :
选择 segue 并在属性检查器中为其命名:
从按钮中删除 segue 后,您现在可以将按钮连接到
@IBAction
方法:performSegue(withIdentifier:sender:)
当您完成验证逻辑时,您的登录操作应该: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
了,其中我提取了一些保留字符: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 }() }
推荐阅读
- algorithm - 最短路径算法的时间复杂度
- javascript - 如何使用 Bootstrap 创建响应式轮播嵌入式卡片?
- mysql - 使用 sql 查询重新排序记录(重写为单个查询)
- r - 如何在R中生成具有特定开始日期/时间的日期和时间序列
- android - 如何清理一些EditText?
- javascript - 我的按钮在移动设备上不起作用,但在桌面上可以正常工作?
- kotlin - Kotlin 默认构造函数
- cmake - 将 libconfig++ 添加到 CMake
- java - 如何检索jComboBox中绑定在数据库表中的对象并将其存储到另一个表中
- oracle - 如何在 oracle 报表参数表单中使用绑定变量?