Swift函数在另一个函数完成后执行

时间:2017-02-21 06:53:07

标签: swift swift3 closures grand-central-dispatch completionhandler

嗨我遇到问题我试图在另一个功能完全完成后调用函数,我尝试使用闭包,但仍然没有帮助和应用程序呈现新的控制器,然后我得到执行登录的功能的响应向服务器发出请求。如何解决?

   performLogin(userName: UserDefaults.standard.value(forKey: "saved_username")! as! String, password: UserDefaults.standard.value(forKey: "saved_password")! as! String){ () -> () in
            self.finishLoggingIn()
        }

向服务器发出请求的功能:

 public func performLogin(userName: String, password: String, complete: ()->()){

    let duom = LoginModel()
    duom.JsonResult(param1: userName, param2: password, param3: self){ () -> () in
}}

打开另一个控制器的功能:

 func finishLoggingIn() {
    print("Finish logging in")


    let appDelegate = UIApplication.shared.delegate! as! AppDelegate

    let initialViewController = self.storyboard!.instantiateViewController(withIdentifier: "MainVC")
    appDelegate.window?.rootViewController = initialViewController
    appDelegate.window?.makeKeyAndVisible()

    UserDefaults.standard.setValue(true, forKey: "isLoggedIn")
    UserDefaults.standard.synchronize()
    dismiss(animated: true, completion: nil)
}

Json结果函数:

internal func JsonResult (param1: String, param2: String, param3: UIViewController, complete:@escaping ()->()){

Json().login(userName: param1, password: param2) { (json, error) in


    if error != nil {
        //Show alert
        print(error!.localizedDescription)
        DispatchQueue.main.async {
            AlertController.showErrorWith(title: "Error", message: error!.localizedDescription, controller: param3) {

            } 
        }


    }

    //Access JSON here

    if let jsonDic = json as? JSON {

        if (jsonDic["result"].exists()){
                 print(jsonDic["result"]["ubus_rpc_session"].stringValue)
              if (jsonDic["result"].arrayValue.contains(6)) {
                 self.loginToken = "[6]"
              } else {
                 for item in jsonDic["result"].arrayValue {
                 self.loginToken = item["ubus_rpc_session"].stringValue
                               }
              }
        }
         if (jsonDic["error"].exists()){

                self.loginToken = jsonDic["error"]["message"].stringValue

                }
    }
    print(self.loginToken)

  if (!self.loginToken.isEmpty) {

     if ((!self.loginToken.contains("[6]")) && (!self.loginToken.contains("Failed"))) {

        UserDefaults.standard.setValue(self.loginToken, forKey: "saved_token")
               print(self.loginToken)



    }else {
        if (self.loginToken.contains("Access denied")) {
            self.loginToken = "Access denied"
            print(self.loginToken)
        } else if (self.loginToken.contains("Failed")) {
            self.loginToken = "Connection timeout"
        } else if (self.loginToken.contains("[6]")) {
            DispatchQueue.main.async {
                AlertController.showErrorWith(title: "Error", message: "Wrong username or password", controller: param3) {

                }
            }
            self.loginToken = "Login Error"
            print(self.loginToken)
        }


    }
    }
    self.loginToken = ""
}
   complete()


}

2 个答案:

答案 0 :(得分:1)

当来自api的performLogin的响应来时,你需要调用finishLoggingIn()函数

duom.JsonResult(param1: userName, param2: password, param3: self){ () -> () in
self.finishLoggingIn()
}}

答案 1 :(得分:1)

第一

您永远不会调用performLogin的完成处理程序:

public func performLogin(userName: String, password: String, complete: ()->()){

    let duom = LoginModel()
    duom.JsonResult(param1: userName, param2: password, param3: self){ () -> () in
        complete() // this line was missing  
    }
}

第二

JsonResult方法中(请启动方法名称小写!),您将在Json().login完成闭包之外调用完成闭包。因此,在JsonResult完成之前调用Json().login完成闭包。

要解决这个问题,请从JsonResult完成闭包中调用Json().login完成闭包:

internal func JsonResult (param1: String, param2: String, param3: UIViewController, complete:@escaping ()->()){

    Json().login(userName: param1, password: param2) { (json, error) in
        if error != nil {
            //Show alert
            print(error!.localizedDescription)
            DispatchQueue.main.async {
                AlertController.showErrorWith(title: "Error", message: error!.localizedDescription, controller: param3) {

                }
            }
        }

        //Access JSON here

        if let jsonDic = json as? JSON {
            if (jsonDic["result"].exists()){
                print(jsonDic["result"]["ubus_rpc_session"].stringValue)
                if (jsonDic["result"].arrayValue.contains(6)) {
                    self.loginToken = "[6]"
                } else {
                    for item in jsonDic["result"].arrayValue {
                        self.loginToken = item["ubus_rpc_session"].stringValue
                    }
                }
            }
            if (jsonDic["error"].exists()){        
                self.loginToken = jsonDic["error"]["message"].stringValue                
            }
        }
        print(self.loginToken)

        if (!self.loginToken.isEmpty) {

            if ((!self.loginToken.contains("[6]")) && (!self.loginToken.contains("Failed"))) {
                UserDefaults.standard.setValue(self.loginToken, forKey: "saved_token")
                print(self.loginToken)        
        } else {
                if (self.loginToken.contains("Access denied")) {
                    self.loginToken = "Access denied"
                    print(self.loginToken)
                } else if (self.loginToken.contains("Failed")) {
                    self.loginToken = "Connection timeout"
                } else if (self.loginToken.contains("[6]")) {
                    DispatchQueue.main.async {
                        AlertController.showErrorWith(title: "Error", message: "Wrong username or password", controller: param3) {

                        }
                    }
                    self.loginToken = "Login Error"
                    print(self.loginToken)
                }        
            }
        }
        self.loginToken = ""
        complete() // moved here to be called after Json().login finished
    }
    //complete()
}