В appDelegate я проверю, авторизован ли пользователь через функцию userAuthorizedCheck()
. В зависимости от результата перенаправьте его на тот или иной стройБорд. userAuthorizedCheck()
должен возвращать результат только после ответа сервера. Проблема в том, что если я оставляю последние completion(false)
в userAuthorizedCheck()
, то сначала возвращается false, а затем проверяется. Даже если проверка прошла успешно, все равно сначала отправляется completion(false)
, и в результате перенаправление отправляется на раскадровку авторизации.
Но если я удалю последний completion(false)
, то получу Thread 1: signal SIGABRT
, противоположное func application (). print (tempToken)
срабатывает после проверки userAuthorizedCheck (). Если я поставлю точку останова, то увижу, что в функции userAuthorizedCheck ()
последний completion (false)
работает первым.
AppDelegate:
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
var storyboardName: String = ""
userAuthorizedCheck(after: { (succesful) in
if (succesful == true){
storyboardName = "Main"
}else{
print(false)
storyboardName = "Authorization"
}
})
let storyboard = UIStoryboard(name: storyboardName, bundle: Bundle.main)
window = UIWindow(frame: UIScreen.main.bounds)
window!.makeKeyAndVisible()
window!.rootViewController = storyboard.instantiateInitialViewController()
return true
}
func userAuthorizedCheck(after completion: @escaping (Bool) -> Void) {
let username : String = UserDefaults.standard.string(forKey: "username") ?? ""
let password : String = UserDefaults.standard.string(forKey: "password") ?? ""
let tokenSaved : String = UserDefaults.standard.string(forKey: "token") ?? ""
var tempToken:String = ""
//
if(!username.isEmpty && !password.isEmpty)
{
let json: [String: String] = ["username": username, "password": password]
login(json: json, after: {(status, token, code) in
if(code == 200 && !token.isEmpty){
UserDefaults.standard.setValue(token, forKey: "token");
UserDefaults.standard.synchronize();
tempToken = token
print(tempToken)
completion(true)
}
else{
tempToken = ""
completion(false)
}
})
}
else
{
completion(false)
}
completion(false)//The problem in this line, as I repent
}
логин (в другом swift-файле):
func login(json:Any, after completion: @escaping (Bool, _ token: String, _ code:Int) -> Void){
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
let sessionConfig = URLSessionConfiguration.default
sessionConfig.timeoutIntervalForRequest = 5.0
sessionConfig.timeoutIntervalForResource = 60.0
URLSession(configuration: sessionConfig).dataTask(with: request){(data, response, error) in
if error != nil{
print("server error")
completion(true, "", 0)
}
else if let response = response{
// print(response)
if let httpResponse = response as? HTTPURLResponse{
guard let data = data else{return}
do{
// print(data)
if(httpResponse.statusCode == 200){
if let json_response = try JSONSerialization.jsonObject(with: data, options: [])as? [String:Any]{
if let token = json_response["auth_token"]{
print(token as! String)
completion(true, "token",httpResponse.statusCode)
}
}
}
else if(httpResponse.statusCode == 400)
{
completion(true, "",httpResponse.statusCode)
print("The username or password you entered is incorrect")
}
else{
print("Unknown error")
completion(true, "", 0)
}
}
catch{
print("errasd")
print(error)
completion(true, "", 0)
}
}
}
}.resume()
}
Я хочу, чтобы пользовательская функция Authorized Check ()
отправляла результат только после ответа сервера.