2016-01-20 29 views
6

Yükleme isteğim başarısız olduğunda yeniden deneme mantığının nasıl uygulanacağı konusunda biraz kaydım.Swift "yeniden deneme" mantığı istek üzerine

İşte ben

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

Kontrol dışarı cevabım Benzer bir soru için: http://stackoverflow.com/a/38720898/319805 – MNassar

cevap

14

Burada geri aramalar hariç, herhangi bir parametre olan herhangi zaman uyumsuz işlevine uygulanabilecek bir genel çözüm nasıl yapılacağı konusunda kılavuzluk istiyorum benim kodudur. Sadece success ve failure geri aramaları ile mantığı basitleştirdim, progress eklemek çok zor olmamalı.

Yani, varsayarak işlevi bu gibi olduğunu:

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() 
    }) 
} 

böyle olmazdı eşleşen bir retry fonksiyonu:

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) 
      } 
     }) 
} 

ve bunun gibi çağrılabilir:

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

Yukarıdakiler, üç kez startUploading numaralı çağrıyı yeniden dener. Başarısız kalır, aksi takdirde ilk başarıda duracaktır.

Düzenle. eğer öyleyse size ağ çağrısından sonra nesneyi yapmak

İşte
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

"Yeniden" ifadesinin ne anlama geldiğini sorabilir miyim? "Yeniden deneme (3, {update, kullanıcı hesabındaki (yeni kullanıcı adı, başarı, başarısızlık) hata) "? Teşekkürler. – allenlinli

+2

@allenlinli" in' burada "Swift'in bir kapanış argümanları ve onun gövdesi arasındaki ayırıcısını temsil eder. – Cristik

2

Ben de başarı bloğunda genel bir nesne ekledi hızlı 3 için güncelleştirilmiş yanıt: diğer params var Fonksiyonlar sadece bir kapatma gömülebilir tamamlandıktan sonra son kapanışa geçebilirsiniz. İşte yeniden deneme fonksiyonudur:

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) 
    } 
    } 
} 

Ve burada bir kullanıcı güncellenmiş ve güncellenmiş bilgi ile yeni bir kullanıcı nesnesi geri almak istiyorsa, bunu kullanan nasıl:

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

Merhaba Justin, bu işlevle kullanılabilir: func dataTask (istek ile birlikte: URLRequest, completionHandler: @escaping (Veri ?, URLResponse ?, Hata?) -> Void) -> URLSessionDataTask Teşekkür ederiz – lveselovsky

İlgili konular