ios - iOS - Swift:在主线程中从数据库中获取数据,而不是在后台
问题描述
在我的 iOS 应用程序中,我可以从数据库下载数据,但实际上所有操作都是在后台进行的,主线程仍然处于活动状态,甚至是 GUI。我也试着和
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(3)) { ... }
有了这个延迟,一切都可以正常工作,但这不是一个好的解决方案。如何更改我的代码以在主线程中执行此操作?可能与 loadingIndicator。
这是我的代码(检查用户名是否存在):
func CheckIfUsernameExists(username : String, passwordFromDb : inout String, errorMsg : inout String)
{
//declare parameter as a dictionary which contains string as key and value combination. considering inputs are valid
var _errorMsg = ""
var _psw = ""
var parameters : [String : Any]?
parameters = ["username": username,
"action": "login"]
print(parameters!)
let session = URLSession.shared
let url = "http://www.thetestiosapp.com/LoginFunctions.php"
let request = NSMutableURLRequest()
request.url = URL(string: url)!
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField:"Accept")
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField:"Content-Type")
do{
request.httpBody = try JSONSerialization.data(withJSONObject: parameters!, options: .sortedKeys)
let task = session.dataTask(with: request as URLRequest, completionHandler: {(data, response, error) in
if let response = response {
let nsHTTPResponse = response as! HTTPURLResponse
let statusCode = nsHTTPResponse.statusCode
print ("status code = \(statusCode)")
}
if let error = error {
print ("\(error)")
}
if let data = data {
do{
_psw = self.parseJSON_CheckIfUsernameExists(data, errorMsg: &_errorMsg)
}
}
})
task.resume()
}catch _ {
print ("Oops something happened buddy")
errorMsg = "Usarname non recuperato (1)"
}
passwordFromDb = _psw
errorMsg = _errorMsg
}
解决方案
您正在尝试更新passwordFromDb
并errorMsg
在此方法结束时。但这是一个异步方法,并且那些局部变量_psw
和_errorMsg
设置在闭包内。与其尝试将这些变量的检查推迟到任意三秒钟,不如在闭包内移动您需要的任何“发布请求”处理。例如
func CheckIfUsernameExists(username : String, passwordFromDb : inout String, errorMsg : inout String) {
//declare parameter as a dictionary which contains string as key and value combination. considering inputs are valid
let parameters = ...
let session = URLSession.shared
var request = URLRequest()
...
do {
request.httpBody = ...
let task = session.dataTask(with: request) { data, response, error in
if let httpResponse = response as? HTTPURLResponse,
let statusCode = httpResponse.statusCode {
print ("status code = \(statusCode)")
}
guard let data = data else {
print (error ?? "Unknown error")
return
}
let password = self.parseJSON_CheckIfUsernameExists(data, errorMsg: &_errorMsg)
DispatchQueue.main.async {
// USE YOUR PASSWORD AND ERROR MESSAGE HERE, E.G.:
self.passwordFromDb = password
self.errorMsg = _errorMsg
// INITIATE WHATEVER UI UPDATE YOU WANT HERE
}
}
task.resume()
} catch _ {
print ("Oops something happened buddy")
errorMsg = "Usarname non recuperato (1)"
}
}
推荐阅读
- javascript - 当字符串在双引号内有单引号时,如何在Javascript中将此字符串转换为JSON对象
- excel - Workbook.close 导致 sub 退出
- c++ - 如何运行 Wave 快速入门示例?
- vba - PowerPoint 加载项 将文本框添加到所选幻灯片
- c# - 在实现具有默认方法实现的接口的类上使用`GetMethod`返回null
- c# - LINQ 在更大的集合中找到一组值的 MAX 值
- mysql - 执行灵活搜索查询时无法评估表达式方法引发“java.lang.illegalargumentexception”异常
- android - 无法使用 FileProvider 与其他应用共享图像文件
- javascript - 网页上的 Javascript 空白页
- node.js - 查询 MongoDB 问题