Правильное использование DispatchQueue при быстром входе - PullRequest
1 голос
/ 03 мая 2020

Я не использую должным образом функцию DispatchQueue, поскольку мне приходится нажимать 2-3 раза, чтобы изменить экран, поскольку данные не загружаются вовремя. Я пробовал пару позиций в коде, но я всегда получаю один и тот же результат. Что такое правильное использование? Вот мой код:

func startLogin() {

    userNameData = userName.text!.trimmingCharacters(in: .whitespacesAndNewlines)
    passwordData = password.text!.trimmingCharacters(in: .whitespacesAndNewlines)

    if userNameData == "" || passwordData == "" { return } else {

        let parameters = "{\n\t\"user\": \"\(userNameData)\",\n\t\"password\": \"\(passwordData)\"\n}"
        let postData = parameters.data(using: .utf8)

        var request = URLRequest(url: URL(string: "https://someurl.io:18999/salesAPI/login")!,timeoutInterval: Double.infinity)
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")

        request.httpMethod = "POST"
        request.httpBody = postData

        let task = URLSession.shared.dataTask(with: request) { data, response, error in
            guard let data = data else {
                print(String(describing: error))
                print("User no encontrado!")

                return
            }

            print(String(data: data, encoding: .utf8)!)
            // semaphore.signal()

            let decoder = JSONDecoder()

            do {
                let jsonPetitions = try decoder.decode(Token.self, from: data)
                token = jsonPetitions.access_token

                let defaults = UserDefaults.standard
                defaults.set(true, forKey: "didLogin")
                defaults.set(userNameData, forKey: "userNameData")
                defaults.set(passwordData, forKey: "passwordData")
                defaults.set(token, forKey: "enterKey")

            }
            catch {
                print("No Json output!!")
                return

            }

        }

        func changeScreen() {

            // performSegue(withIdentifier: "switchScreens", sender: nil)

            let homeViewController = self.storyboard?.instantiateViewController(identifier: Constance.Storyboard.homeViewController) as? HomeViewController
            self.view.window?.rootViewController = homeViewController
            self.view.window?.makeKeyAndVisible()

        }

        dispatchGroup.enter()

        task.resume()

        self.dispatchGroup.leave()

        dispatchGroup.notify(queue: DispatchQueue.main) {
            if token == "" {

                self.errorLabel.alpha = 0.5
                self.errorLabel.text = "Algun dato esta mal"
                self.errorLabel.textColor = UIColor.red
                print ("No Token! User or the pass is wrong")

            } else {
                changeScreen()
            }

        }

    } // end User Login
}

Код является лишь частью этого, но все важные части там

1 Ответ

1 голос
/ 03 мая 2020

Группа отправки не используется правильно. Но вместо того, чтобы пытаться это исправить, мы должны просто удалить это, так как это не нужно. Просто переместите код внутри блока notify в замыкание dataTask после анализа данных.

Например:

func startLogin() {
    userNameData = userName.text!.trimmingCharacters(in: .whitespacesAndNewlines)
    passwordData = password.text!.trimmingCharacters(in: .whitespacesAndNewlines)

    if userNameData == "" || passwordData == "" { return }

    let parameters = ["user": userNameData, "password": passwordData]

    var request = URLRequest(url: URL(string: "https://someurl.io:18999/salesAPI/login")!,timeoutInterval: Double.infinity)
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")

    request.httpMethod = "POST"
    request.httpBody = try! JSONEncoder().encode(parameters)

    let task = URLSession.shared.dataTask(with: request) { data, response, error in
        guard let data = data else {
            print(String(describing: error))
            print("User no encontrado!")

            return
        }

        let decoder = JSONDecoder()

        do {
            let jsonPetitions = try decoder.decode(Token.self, from: data)
            token = jsonPetitions.access_token

            let defaults = UserDefaults.standard
            defaults.set(true, forKey: "didLogin")
            defaults.set(userNameData, forKey: "userNameData")
            defaults.set(passwordData, forKey: "passwordData")
            defaults.set(token, forKey: "enterKey")

            DispatchQueue.main.async {
                if token == "" {
                    self.errorLabel.alpha = 0.5
                    self.errorLabel.text = "Algun dato esta mal"
                    self.errorLabel.textColor = UIColor.red
                    print ("No Token! User or the pass is wrong")
                } else {
                    self.changeScreen()
                }
            }
        } catch {
            print("No Json output!!")
            return
        }
    }

    task.resume()
}

func changeScreen() {
    // performSegue(withIdentifier: "switchScreens", sender: nil)

    let homeViewController = self.storyboard?.instantiateViewController(identifier: Constance.Storyboard.homeViewController) as? HomeViewController
    self.view.window?.rootViewController = homeViewController
    self.view.window?.makeKeyAndVisible()
}
...