AppDelegate:
func userAuthorized() -> Bool { let username : String = UserDefaults.standard.string(forKey: "username") ?? "" let password : String = UserDefaults.standard.string(forKey: "password") ?? "" var tempToken:String = "" if(!username.isEmpty && !password.isEmpty)//потом это { let json: [String: String] = ["username": username, "password": password] login(json: json) { [weak self] token, code in guard let self = self else { return } guard let token = token, !token.isEmpty else { print("error") return } print("ok") print(token) tempToken = token print("temp " + tempToken) UserDefaults.standard.setValue(username, forKey: "userEmail"); UserDefaults.standard.setValue(password, forKey: "userPassword"); UserDefaults.standard.setValue(token, forKey: "token"); UserDefaults.standard.synchronize(); } } else { return false } if(!tempToken.isEmpty){// сначало это вызывается return true } return false }
REST module:
func login(json: Any, callback: @escaping (_ token: String?, _ code: Int?) -> ()) { guard let url = URL(string: ngrok+"/api/auth/token/create")else{return} var request = URLRequest(url: url) request.httpMethod = "POST" request.setValue("application/json", forHTTPHeaderField:"Content-Type") guard let httpBody = try? JSONSerialization.data(withJSONObject: json, options: [])else {return} request.httpBody = httpBody URLSession(configuration: .default).dataTask(with: request){(data, response, error) in if let response = response{ print(response) } if let error = error{ print(error) } if let httpResponse = response as? HTTPURLResponse{ guard let data = data else{return} do{ print(data) if let json_response = try JSONSerialization.jsonObject(with: data, options: [])as? [String:Any]{ if let temp_token = json_response["auth_token"]{ print(temp_token as! String) DispatchQueue.main.async { callback(temp_token as? String, httpResponse.statusCode) } } } } catch{ print(error) } } }.resume() }
Two problems:
1) I look at the server logs and see the code 200, and !tempToken.isEmpty
issues an empty token. Put a stop point and really, first checked !tempToken.isEmpty
, and then comes the login function call. Why is that? Is this because the login function is asynchronous? Then how can you wait for its execution (successful or not), and then check tempToken? Or is it a bad decision?
2) I just can not catch the error when the server is turned off. Put a stop point and that's what I get: comes to URLSession(configuration: .default).dataTask(with: request){(data, response, error)
, and then immediately to resume()
and print(error)
does not output anything. Surely this is again due to asynchrony.
I see only one option - to make the login function synchronous, if possible. But I'm not sure how good this decision is, if by default it goes asynchronous.
By the way, if you call the function from the loginView, then everything works fine, I don’t think that it’s impossible to catch the error with the server turned off:
@IBAction func loginButtonTapped(_ sender: Any) { let userEmail = emailOrUsernameField.text; let userPassword = passwordField.text; if(userEmail!.isEmpty || userPassword!.isEmpty){ self.errorLabel.text = "Не все поля заполенны" if(userEmail!.isEmpty && !userPassword!.isEmpty){ textFieldsColor(textField: emailOrUsernameField, color: redBorder ) } else if (!userEmail!.isEmpty && userPassword!.isEmpty){ textFieldsColor(textField: passwordField, color: redBorder) } else{ textFieldsColor(textField: emailOrUsernameField, color: redBorder) textFieldsColor(textField: passwordField, color: redBorder) } }else { let json: [String: String] = ["username": userEmail!, "password": userPassword!] login(json: json) { [weak self] token, code in guard let self = self else { return } guard let token = token, !token.isEmpty else { print("error") self.errorLabel.text = "Невенрный логин или пароль." return } print(code) self.errorLabel.text = "" UserDefaults.standard.setValue(userEmail, forKey: "username"); UserDefaults.standard.setValue(userPassword, forKey: "password"); UserDefaults.standard.setValue(token, forKey: "token"); UserDefaults.standard.synchronize(); let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main) self.window = UIWindow(frame: UIScreen.main.bounds) self.window!.makeKeyAndVisible() self.window!.rootViewController = storyboard.instantiateInitialViewController() } } }