そのため、アップロード要求が失敗したときに再試行ロジックを実装する方法に少し迷っています。
これが私のコードですそれを行う方法についてのガイダンスが欲しいです
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()
})
}
これは、コールバックを除いて、パラメーターを持たないすべての非同期関数に適用できる一般的なソリューションです。 success
とfailure
のコールバックだけを使用してロジックを簡略化しましたが、progress
を追加するのはそれほど難しくありません。
したがって、関数が次のようになっていると仮定します。
func startUploading(success: @escaping () -> Void, failure: @escaping (Error) -> Void) {
DDLogDebug("JogUploader: Creating jog: \(self.jog)")
API.sharedInstance.createJog(self.jog,
failure: { error in
failure(error)
}, success: {_ in
success()
})
}
一致するretry
関数は次のようになります。
func retry(times: Int, task: (success: @escaping () -> Void, failure: @escaping (Error) -> Void) -> Void, success: @escaping () -> Void, failure: @escaping (Error) -> Void) {
task(success: success,
failure: { error in
// do we have retries left? if yes, call retry again
// if not, report error
if times > 0 {
retry(times - 1, task: task, success: success, failure: failure)
} else {
failure(error)
}
})
}
そしてこのように呼ぶことができます:
retry(times: 3, task: startUploading,
success: {
print("Succeeded")
},
failure: { err in
print("Failed: \(err)")
})
上記は、失敗し続ける場合はstartUploading
呼び出しを3回再試行し、それ以外の場合は最初の成功で停止します。
編集。他のパラメータを持つ関数は、クロージャに簡単に埋め込むことができます。
func updateUsername(username: String, success: @escaping () -> Void, failure: @escaping (Error) -> Void) {
...
}
retry(times: 3, { success, failure in updateUsername(newUsername, success, failure) },
success: {
print("Updated username")
},
failure: {
print("Failed with error: \($0)")
}
)
Swift 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)
}