2016-11-29 5 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 
     } 
    }  
} 

私の最初の考えは絵に再帰を持参し、再帰的に「performTokenExchange」コールバックの中に「someAPICall」を呼び出すことであろう、しかし私は "performTokenExchange"コールバックの中で明示的にそれを管理せずに "someCall"を扱う方法を知らず、私の "恐ろしいネストされた呼び出し"の問題で私を戻します。

+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

ああ、すごくいいですよ、私はそれに亀裂を与え、あなたを更新します!これは、オプションの自慢のスウィフトがやるべきことのようなものです –

関連する問題