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 модуль:
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()
}
Две проблемы:
1) Смотрю на логи сервера и вижу код 200, а !tempToken.isEmpty выдает пустой токен. Поставил точки остановки и действительно, сначала проверяется !tempToken.isEmpty, а потом идет вызов login функции. Почему так? Это из-за того, что login функция асинхронна? Тогда можно как то дождаться её выполнения(успешного или нет), а потом проверять tempToken? Или это плохое решение?
2) Никак не могу отловить ошибку, когда сервер выключен. Поставил точки остановки и вот, что получаю: доходит до URLSession(configuration: .default).dataTask(with: request){(data, response, error) , а потом сразу на resume() и print(error) ничего не выводит. Наверняка это опять из-за асинхронности.
Вижу только один вариант - сделать login функцию синхронной, если это возможно. Но не уверен насколько это хорошие решение, если по дефолту она идет асинхронной.
Кстати, если вызвать функцию из loginView, то все нормально работает, не считаю того, что отловить ошибку с выключенным сервером все равно не получается:
@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()
}
}
}