Skip to content

Commit c9f6279

Browse files
authored
Merge pull request #47 from allanlang/await-network-retry
Various networking robustness measures
2 parents 86f394e + a46f3ce commit c9f6279

File tree

3 files changed

+38
-1
lines changed

3 files changed

+38
-1
lines changed

Tree Tracker/Constants.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,10 @@ enum Constants {
1313
static let cloudName = Secrets.cloudinaryCloudName
1414
static let uploadPresetName = Secrets.cloudinaryUploadPresetName
1515
}
16+
enum Http {
17+
static let requestWaitsForConnectivity = true
18+
static let requestTimeoutSeconds: TimeInterval = 30
19+
static let requestRetryDelaySeconds = 5
20+
static let requestRetryLimit = 3
21+
}
1622
}

Tree Tracker/Services/AlamofireApi.swift

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,21 @@ final class AlamofireApi: Api {
2020
}
2121
}
2222

23-
private let session = Session()
23+
private let session: Session
2424
private let logger: Logging
2525
private var imageLoaders = [String: PHImageLoader]()
2626

2727
init(logger: Logging = CurrentEnvironment.logger) {
2828
self.logger = logger
29+
30+
let sessionConfig = URLSessionConfiguration.af.default
31+
sessionConfig.timeoutIntervalForRequest = Constants.Http.requestTimeoutSeconds
32+
sessionConfig.waitsForConnectivity = Constants.Http.requestWaitsForConnectivity
33+
34+
self.session = Session(configuration: sessionConfig,
35+
interceptor: RetryingRequestInterceptor(retryDelaySecs: Constants.Http.requestRetryDelaySeconds,
36+
maxRetries: Constants.Http.requestRetryLimit))
37+
2938
}
3039

3140
func treesPlanted(offset: String?, completion: @escaping (Result<Paginated<AirtableTree>, AFError>) -> Void) {
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import Alamofire
2+
import Foundation
3+
4+
class RetryingRequestInterceptor: RequestInterceptor {
5+
var maxRetries: Int = 5
6+
var retryDelay: TimeInterval = 10
7+
8+
init(retryDelaySecs: Int, maxRetries retryLimit: Int) {
9+
self.retryDelay = TimeInterval(retryDelaySecs)
10+
self.maxRetries = retryLimit
11+
}
12+
13+
func retry(_ request: Request, for session: Session, dueTo error: Error, completion: @escaping (RetryResult) -> Void) {
14+
let response = request.task?.response as? HTTPURLResponse
15+
16+
if let statusCode = response?.statusCode, (500...599).contains(statusCode), request.retryCount < maxRetries {
17+
completion(.retryWithDelay(retryDelay))
18+
} else {
19+
return completion(.doNotRetry)
20+
}
21+
}
22+
}

0 commit comments

Comments
 (0)