2016-05-24 6 views
8

Alamofire要求/応答が処理されるコードには、多くの場所があります。再試行でAlamofire要求を行う方法はありますか

これらの要求のそれぞれは、断続的な問題(最も一般的なのはフレークネットワークです)が原因で失敗する可能性があります。

私はリクエストを3回再試行してから救済することができます。

簡単な方法は、その

var errorCount = 0 
func requestType1() { 
    let request = Alamofire.request(...).responseJSON { response in 
     if (isError(response) && errorCount < 3) { 
      errorCount += 1 
      request1() 
     } 
     if (isError(response)) { 
      handleError() 
     } 

     handleSuccess() 
    } 
} 

のようなものを持つことになりますしかし、私はこのアプローチを複数の理由から、LOTを嫌います。最も明白なのは、各リクエストの種類ごとにそのようなコードを実装する必要があることです(そして、私は15種類あるようです)。

私は(変更が最小限と非侵入している)のようなもの、あなたがこれを使用することができますされスウィフトと取得構文糖のビットの

let request = Alamofire.request(..., **3**) 
+0

あなたは終了ブロックとして要求を取るラッパーを作るだろうか?したがって、リクエストを直接呼び出す代わりに、ブロック内に同じリクエストコードがありますが、ラッパーを呼び出します。コードを簡単に変更できます。 – Carlos

+0

カルロス。私はあなたが正しいと思います。私はこれを見落とした:)。あなたは答えとして書きたいですか? –

+0

確かに、少し時間を与えて、私はそれをします – Carlos

答えて

3

一つを行う方法があるかどうか骨董品を午前:

UPDAのブロックが(外側にある

updateEvents(someNormalParam: false) {...} 

注):このよう

public func updateEvents(someNormalParam: Bool = true, someBlock: (Void->Void)) 

あなたが通常それを期待していたところに反して、teEvents関数。ブロックが関数宣言の最後のものである場合にのみ機能します。

つまり、Alamofireリクエストなどのブロックが発生した場合は、再試行機能で効果的にラップすることができます。少し複雑な問題の1つは、ブロック内のブロックを呼び出すことです。ではない大した:

func retryWrapper(alamoBlock: (Void->Request)) { 
    alamoblock().responseJSON() { 
     //Your retry logic here 
    } 
} 

そして、あなたがそうのようにそれを使用します。

retryWrapper() { 
    Alamofire.request(method, targetUrl, parameters: parameters, encoding: encoding) 
} 

意味あなたがしなければならないすべてはあなたのAlamofire呼び出しを見つけると、{}でそれらをラップし、()の前にretryWrapperを入れています。再試行ロジック自体は1回だけ存在します。

+0

私はここで少し混乱しています。私たちは何を返答しますか? – Ranjit

+0

私は少し錆びていますが、ブロックがリクエストを返してくれるようですが、リクエストにはJSONに変換する関数があります – Carlos

+0

requestRetrierを使用していますか? – Ranjit

-3

私がしたことは次のとおりです。要求が失敗した場合は、要求を行った人に失敗した通知を送信します。次に、要求の再試行を行います。はるかに簡単にこれが見つかりました。

Alamofire.request(.GET, urlString, parameters: params, headers: defaultHeaders) 
     .validate() 
     .responseJSON 
     { 
      response in 

      switch response.result 
      { 
      case .Success: 
       print("Request Successful") 

       let json = JSON(data:response.data!) 

       NSNotificationCenter.defaultCenter().postNotificationName(SUCCESS_NOTIFICATION, object: movieArray) 

      case .Failure(let error): 
       print("Request Failed with error \(error)") 
       NSNotificationCenter.defaultCenter().postNotificationName(FAILURE_NOTIFICATION, object: error) 
      } 
    } 
+2

私はこのアプローチをお勧めしません。 NSNotificationsの使用においてより賢明であることが賢明です。あなたがそれらを使用している場合は、より良いアプローチがないかどうか自問してください。 たとえば、この場合、コールバックを行うためにクロージャを使用するほうがずっと良いでしょう。完了ハンドラとしてクロージャを使用することは、この種の事例の標準的な習慣とパターンです。 –

10

Alamofire 4.0は、あなたが使用することができますRequestRetrierプロトコルを持っています。

https://github.com/Alamofire/Alamofire/blob/master/Documentation/Alamofire%204.0%20Migration%20Guide.md#request-retrier

例:

class OAuth2Handler: RequestAdapter, RequestRetrier { 
    public func should(_ manager: SessionManager, retry request: Request, with error: Error, completion: RequestRetryCompletion) { 
     if let response = request.task.response as? HTTPURLResponse, response.statusCode == 401 { 
      completion(true, 1.0) // retry after 1 second 
     } else { 
      completion(false, 0.0) // don't retry 
     } 
    } 
} 

let sessionManager = SessionManager() 
sessionManager.retrier = OAuth2Handler() 

sessionManager.request(urlString).responseJSON { response in 
    debugPrint(response) 
} 
1

私は、同じ問題を抱えていた要求がRequestRetrier、should方法とrequest.retryCountを使用して再試行するようになってきました。そのような何か: ` // MARK: - RequestRetry

public func should(_ manager: SessionManager, retry request: Request, with error: Error, completion: @escaping RequestRetryCompletion) { 
    lock.lock() ; defer { lock.unlock() } 


    if let response = request.task?.response as? HTTPURLResponse{ 
     if response.statusCode == 401 { 
      requestsToRetry.append(completion) 

      getToken { (expires, _) in 
       _ = SessionCountdownToken.sharedInstance.startCount(expirationTime: expires) 
      } 
     } else { 

      if request.retryCount == 3 { completion(false, 0.0); return} 
      completion(true, 1.0) 
      return 
     } 
    } else { 
     completion(false, 0.0) 
    } 
}` 
関連する問題