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

Posted

技术标签:

【中文标题】Swift函数在另一个函数完成后执行【英文标题】:Swift function execute after another function done 【发布时间】:2017-02-21 06:53:07 【问题描述】:

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

   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

打开另一个Controller的功能:

 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()



【问题讨论】:

检查这个答案:***.com/a/30401560/4831524 【参考方案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().logins 完成闭包之外调用完成闭包。结果JsonResults 完成闭包在Json().login 完成之前被调用。

要解决此问题,请从 Json().logins 完成闭包中调用 JsonResults 完成闭包:

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()

【讨论】:

谢谢你,完全是我要找的东西【参考方案2】:

需要在api的performLogin响应来时调用finishLoggingIn()函数

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

【讨论】:

这个我试过了,还是一样,我认为是函数JsonResult的问题,我会用它更新问题。

以上是关于Swift函数在另一个函数完成后执行的主要内容,如果未能解决你的问题,请参考以下文章

Angular / TypeScript - 在另一个函数完成后调用一个函数

Swift - 在另一个函数中使用来自 UISlider IBAction 的值

如何在另一个 lambda 之后执行 AWS lambda

如何在 Swift 4 中同步执行多个自定义动画函数

对于 Swift 中的 Apple Watch OS,如何在 WCSession 激活完成后运行函数?

从 swift 评估 javascript 函数,在完成处理程序中得到 nil