首页 > 解决方案 > 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
}

标签: iosswift

解决方案


您正在尝试更新passwordFromDberrorMsg在此方法结束时。但这是一个异步方法,并且那些局部变量_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)"
    }
}

推荐阅读