Почему функция возвращает результат раньше времени? - PullRequest
0 голосов
/ 11 мая 2019

В 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 () отправляла результат только после ответа сервера.

1 Ответ

0 голосов
/ 11 мая 2019

Вы не можете ждать в didFinishLaunchingWithOptions чего-то асинхронного перед возвратом true или false.

Один из вариантов - вернуть true и загрузить раскадровку после ответа сервера

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    userAuthorizedCheck(after: { (succesful) in
        let storyboardName = succesful ? "Main" : "Authorization"
        let storyboard = UIStoryboard(name: storyboardName, bundle: Bundle.main)
        self.window = UIWindow(frame: UIScreen.main.bounds)
        window!.makeKeyAndVisible()
        window!.rootViewController = storyboard.instantiateInitialViewController()
    })

    return true
}

И удалить эту строку в userAuthorizedCheck

completion(false)//The problem in this line, as I repent

потому что он завершается немедленно, что не предназначено.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...