2016-01-20 3 views
6

アップロードリクエストが失敗したときにリトライロジックを実装する方法が少し失われています。リクエスト時にスウィフト「リトライ」ロジック

は、ここで私はそれが

func startUploading(failure failure: (NSError) -> Void, success:() -> Void, progress: (Double) -> Void) { 
     DDLogDebug("JogUploader: Creating jog: \(self.jog)") 

     API.sharedInstance.createJog(self.jog, 
      failure: { error in 
       failure(error) 
      }, success: {_ in 
       success() 
     }) 
    } 
+0

私の答えをチェックしてください同様の質問のために:http://stackoverflow.com/a/38720898/319805 – MNassar

答えて

14

ここでコールバックを除いて、パラメータはありません任意の非同期関数に適用することができ、一般的なソリューションです行う方法についていくつかのガイダンスをしたいと思います私のコードです。 successfailureコールバックだけを持つことでロジックを単純化しましたが、progressはそれほど難しいものではありません。

だから、あなたの関数は次のようであると仮定すると:それは次のようになり、一致

func startUploading(success: Void -> Void, failure: NSError -> Void) { 
    DDLogDebug("JogUploader: Creating jog: \(self.jog)") 

    API.sharedInstance.createJog(self.jog, 
     failure: { error in 
      failure(error) 
     }, success: {_ in 
      success() 
    }) 
} 

retry機能:

func retry(numberOfTimes: Int, task: (success: Void -> Void, failure: NSError -> Void) -> Void, success: Void -> Void, failure: NSError -> Void) { 
    task(success: success, 
     failure: { error in 
      // do we have retries left? if yes, call retry again 
      // if not, report error 
      if numberOfTimes > 1 { 
       retry(numberOfTimes - 1, task: task, success: success, failure: failure) 
      } else { 
       failure(error) 
      } 
     }) 
} 

と、次のように呼び出すことができます。

retry(3, task: startUploading, 
    success: { 
     print("Succeeded") 
    }, 
    failure: { err in 
     print("Failed: \(err)") 
}) 

上記は、startUploadingコールを3回再試行します失敗し続ける、そうでなければ最初の成功で停止する。

を編集します。ここで

func updateUsername(username: String, success: Void -> Void, failure: NSError -> Void) { 
    ... 
} 

retry(3, { success, failure in updateUsername(newUsername, success, failure) }, 
    success: { 
     print("Updated username") 
    }, 
    failure: { 
     print("Failed with error: \($0)") 
    } 
) 
+0

ここでは、 "再試行(3、{成功、失敗のupdateUsername(newUsername、成功、失敗)}" "? ありがとう。 – allenlinli

+2

@allenlinliここで' in'はクロージャ引数とそのボディの間の 'Swift'の区切りを表します。 – Cristik

2

はあなたのネットワーク呼び出した後、オブジェクトを作るので、もし私も成功ブロックに汎用オブジェクトを追加迅速3.更新の答えです:他のparamsは、単に閉鎖に埋め込むことができていない機能それが最後の閉鎖にそれを渡すことができます完了です。ここでリトライ機能は次のとおりです。

func retry<T>(_ attempts: Int, task: @escaping (_ success: @escaping (T) -> Void, _ failure: @escaping (Error) -> Void) -> Void, success: @escaping (T) -> Void, failure: @escaping (Error) -> Void) { 
task({ (obj) in 
    success(obj) 
}) { (error) in 
    print("Error retry left \(attempts)") 
    if attempts > 1 { 
    self.retry(attempts - 1, task: task, success: success, failure: failure) 
    } else { 
     failure(error) 
    } 
    } 
} 

そして、ここでは、ユーザーを更新し、更新情報を持つ新しいユーザーオブジェクトを取り戻すしたい場合は、あなたがそれを使用する方法である:

NetworkManager.shared.retry(3, task: { updatedUser, failure in 
NetworkManager.shared.updateUser(user, success: updatedUser, error: failure) } 
, success: { (updatedUser) in 
    print(updatedUser.debugDescription) 
}) { (err) in 
    print(err) 
} 
+0

こんにちはJustin、 はこの関数で使用することができます:func dataTask(リクエスト:URLRequest、completionHandler:@エスケープ(データ?, URLResponse ?, Error?) - > Void) - > URLSessionDataTask ありがとう – lveselovsky