2016-09-26 6 views
4

私は、AlamofireのSessionManagerを使用してAPIサービスにリクエストしています。Alamofire、セッションマネージャリトライ回数制限

Alamofireのリトライ回数を制限する方法はありますか?

私は新しいRequestAdapterとRequestTrierプロトコルを使用して、Alamofire v4で再試行の仕組みを提供しています。

5回までのリトライを制限したい場合、5回のリトライ後に新しいリクエストをしないでください。

class VMRetrier: RequestAdapter, RequestRetrier { 

public func adapt(_ urlRequest: URLRequest) throws -> URLRequest { 
    return urlRequest; 
} 

func should(_ manager: SessionManager, retry request: Request, with error: Error, completion: @escaping RequestRetryCompletion) { 

    if let response = request.task?.response as? HTTPURLResponse, response.statusCode == 401 { 
     VMLogger.shared.debug(message: "Trying to get a token") 
     let _ = AuthService.shared.login(email: "[email protected]", password: "test34") 
          .then(execute: { (response) in 
           completion(true, 0.0) 
          }) 
    } 
    else { 
     completion(false, 0.0) 
    } 
} } 

使用法:

internal let sessionManager = SessionManager() 

override init() { 
    super.init() 
    sessionManager.adapter = VMRequestAdapter() 
    sessionManager.retrier = VMRetrier() 
} 

UPDATE 新しい再試行回数のオプションを提供するために、alamofireにコミットがあります。 Alamofire Commit

+0

あなたはどんな解決策を見つけたことがありますか? – Footjy

+0

私のアップデート – aymeba

答えて

3

私はAlamofireのRequestRetrierプロトコルでこれを解決した:

class Retrier: RequestRetrier { 

    var defaultRetryCount = 4 
    private var requestsAndRetryCounts: [(Request, Int)] = [] 
    private var lock = NSLock() 

    private func index(request: Request) -> Int? { 
     return requestsAndRetryCounts.index(where: { $0.0 === request }) 
    } 

    func addRetryInfo(request: Request, retryCount: Int? = nil) { 
     lock.lock() ; defer { lock.unlock() } 
     guard index(request: request) == nil else { print("ERROR addRetryInfo called for already tracked request"); return } 

     requestsAndRetryCounts.append((request, retryCount ?? defaultRetryCount)) 
    } 

    func deleteRetryInfo(request: Request) { 
     lock.lock() ; defer { lock.unlock() } 
     guard let index = index(request: request) else { print("ERROR deleteRetryInfo called for not tracked request"); return } 

     requestsAndRetryCounts.remove(at: index) 
    } 

    func should(_ manager: SessionManager, retry request: Request, with error: Error, completion: @escaping RequestRetryCompletion){ 

     lock.lock() ; defer { lock.unlock() } 

     guard let index = index(request: request) else { completion(false, 0); return } 
     let (request, retryCount) = requestsAndRetryCounts[index] 

     if retryCount == 0 { 
      completion(false, 0) 
     } else { 
      requestsAndRetryCounts[index] = (request, retryCount - 1) 
      completion(true, 0.5) 
     } 
    } 
} 

は、この方法を使用する必要があります。その後、

let manager = SessionManager() 
let retrier = Retrier() 
// ... 
manager.retrier = retrier 

let request = manager.request(urlString, method: method, parameters: parameters, encoding: JSONEncoding.default, headers: headers) 

retrier.addRetryInfo(request: request) 

request.response { r in 
    self.retrier.deleteRetryInfo(request: request) 
}.responseApiJSON { (r: DataResponse<JSONObject>) in 
    // You code here 
} 
+0

を参照してくださいこれはAlamofireプロジェクトに組み込まれているといいです – neoneye

+1

ここでセッションマネージャを使用していない場合はどうなりますか?リクエスト・レターを使用する方法 – Ranjit