简体   繁体   中英

iOS - Swift : fetching data from database in main thread, not in background

In my iOS App i'm able to download data from a database, but actually all the operations are made in background and the main thread is still active, even the GUI. I also tried to make a 'sleep' with

DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(3)) { ... }

With this delay everthing works fine, but it's not a good solution. How can i change my code to do this in the main thread? Possibly with loadingIndicator.

This is my code (checking if username exists):

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
}

You're attempting to update passwordFromDb and errorMsg at the end of this method. But this is an asynchronous method and and those local variables _psw and _errorMsg are set inside the closure. Rather than trying to defer the checking of those variables some arbitrary three seconds in the future, move whatever “post request” processing you need inside that closure. Eg

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM