2016-01-20 57 views
6

因此,當我的上傳請求失敗時,如何實現重試邏輯有點失落。按要求提供Swift「重試」邏輯

這裏是我的代碼,我想就如何做到這一點

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呼叫三次,如果它一直失敗,否則會在第一次成功時停止。

編輯。這確實有其他PARAMS功能可以簡單地嵌入封閉:

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,{成功,在更新用戶名失敗(新用戶名,成功,失敗)} 「? 謝謝。 – allenlinli

+2

@allenlinli'in'這裏代表'Swift'在分隔符和它的正文之間的分隔符 – Cristik

2

這裏是迅速3.更新的答案,我也加入了成功的塊中的通用對象,因此,如果你讓一個對象的網絡電話後是完整的,你可以將它傳遞給最終的封閉。這裏是重試功能:

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

Hi Justin, 可能與此函數一起使用:func dataTask(with request:URLRequest,completionHandler:@escaping(Data ?, URLResponse?,Error?) - > Void) - > URLSessionDataTask – lveselovsky