2016-11-29 56 views
1

我的应用使用具有短期满计时器的访问令牌在进行服务器调用时对用户进行身份验证。当使用过期令牌进行呼叫时,服务器以402状态作出响应,并且用户必须发送刷新令牌,以提示服务器发送新的访问令牌。然后,我需要使用与首先完全相同的参数进行相同的服务器调用,但现在使用我的新访问令牌。我怎样才能使这个过程自动化,以便令牌交换发生,并且我们获得了我们最初想要的资源,而没有任何用户输入(即它都发生在后台,用户甚至没有意识到)?我想不出不涉及制造可怕的嵌套调用,像这样的方式:如何为令牌交换创建递归回调,Swift

someAPICall(foo, arg2: bar) { result, error in 
    if let result = result { 
     if result.status == 402 { 
      performTokenExchange(refreshToken) { newAccessToken, error in 
       if newToken { 
        someAPICall(foo, bar) { result, error in 
         //... 
        } 
       } 
      } 
     } 
     else { 
      // ... continue with program 
     } 
    }  
} 

我首先想到的是把递归进入画面,并递归调用“someAPICall”中的“performTokenExchange”回调中,但后来我不知道如何处理“someCall”而没有在“performTokenExchange”回调中明确地管理它,让我回到我的“可怕的嵌套呼叫”问题。

+0

因此'someAPICall'是一个给定的函数,你不写自己,但只能调用并传递完成闭包?我问,因为你已经在函数名称前面使用过'func'。 – Keiwan

+0

@Keiwan哎呀!我的错误 - 意味着显示“someAPICall”的一个实例。它是我自己编写的一个函数 - 编辑我的代码以显示。 –

回答

1

虽然我自己没有尝试过,但我认为在编写闭包时应该能够使用递归,然后在调用它时将它作为参数传递给函数。

var completion: ((Result?, Error?) -> Void)! // change this to whatever types your result and error are 

completion = { result, error in 

    if let result = result { 
     if result.status == 402 { 

      performTokenExchange(refreshToken) { newToken, error in 
       if newToken { 
        someAPICall(foo, bar, completion) 
       } 
      } 
     } else { 
      // ... continue with program 
     } 
    } 
} 

所以你首先声明你的完成闭包作为一个隐式解包可选与它的特定类型。然后,您可以将实际的代码块分配到completion,您可以再次参考completion,因为它是事先声明的。

这样,你应该能够使API调用,如:

someAPICall(foo, bar, completion) 

(就像它也被用来关闭自身内部)

让我知道这是否正常工作! 如上所述,这只是一个想法,没有测试:)

+0

哦,这真棒哈哈我会给它一个裂缝,并更新你!这看起来像是那些可选的Swift应该做的事情 –