diff --git a/AFNetworkDataSource.swift b/AFNetworkDataSource.swift deleted file mode 100644 index 8770c980..00000000 --- a/AFNetworkDataSource.swift +++ /dev/null @@ -1,51 +0,0 @@ -// -// AFNetworkDataSource.swift -// SuperAwesome -// -// Created by Gunhan Sancar on 08/07/2020. -// - -import Alamofire - -class AFNetworkDataSource: NetworkDataSourceType { - func getData(url: String, completion: @escaping OnResultListener) { - AF.request(url).responseData { response in - if let data = response.data { - completion(Result.success(data)) - } else { - completion(Result.failure(AwesomeAdsError.network)) - } - } - } - - func downloadFile(url: String, completion: @escaping OnResultListener) { - let destination: DownloadRequest.Destination = { _, _ in - let fileName = url.toMD5 - let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] - let fileURL = documentsURL.appendingPathComponent(fileName) - - return (fileURL, [.removePreviousFile, .createIntermediateDirectories]) - } - - AF.download(url, to: destination).response { response in - debugPrint(response) - - if response.error == nil, let path = response.fileURL?.path { - completion(Result.success(path)) - } else { - completion(Result.failure(AwesomeAdsError.network)) - } - } - } - - func clearFiles() { - let fileManager = FileManager.default - let documentsURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first! - - do { - try fileManager.removeItem(at: documentsURL) - } catch { - return - } - } -} diff --git a/Example/Shared/Networking/GetPlacements.swift b/Example/Shared/Networking/GetPlacements.swift index 79e02d68..3aead3b5 100644 --- a/Example/Shared/Networking/GetPlacements.swift +++ b/Example/Shared/Networking/GetPlacements.swift @@ -22,7 +22,7 @@ class GetPlacements { guard let url = URL(string: "\(root)/placements.json") else { return nil } let session = URLSession.shared let publisher = session.dataTaskPublisher(for: url) - .tryMap() { element -> Data in + .tryMap { element -> Data in guard let httpResponse = element.response as? HTTPURLResponse, httpResponse.statusCode == 200 else { throw URLError(.badServerResponse) diff --git a/MoyaNetworkDataSource.swift b/MoyaNetworkDataSource.swift deleted file mode 100644 index 273a28ef..00000000 --- a/MoyaNetworkDataSource.swift +++ /dev/null @@ -1,19 +0,0 @@ -// -// MoyaNetworkDataSource.swift -// SuperAwesome -// -// Created by Gunhan Sancar on 06/07/2020. -// - -import Alamofire - -class MoyaNetworkDataSource { - func get(_ url: String, completion: @escaping Completion) { - AF.request(url).responseData { response in - switch response.result { - case .success: completion(Result.success(response.value ?? Data())) - case .failure(let error): completion(Result.failure(error)) - } - } - } -} diff --git a/Pod/Classes/Common/Model/Constants.swift b/Pod/Classes/Common/Model/Constants.swift index a3f74dd4..c5cffd60 100644 --- a/Pod/Classes/Common/Model/Constants.swift +++ b/Pod/Classes/Common/Model/Constants.swift @@ -6,6 +6,12 @@ // struct Constants { + /// Number of retries for each network request before it fails + static let numberOfRetries = 5 + + /// The delay between each request when retrying + static let retryDelay: TimeInterval = 1 + static let defaultClickThresholdInSecs = 5 static let defaultTestMode = false static let defaultParentalGate = false diff --git a/Pod/Classes/Network/DI/NetworkModule.swift b/Pod/Classes/Network/DI/NetworkModule.swift index 42d47376..7166285b 100644 --- a/Pod/Classes/Network/DI/NetworkModule.swift +++ b/Pod/Classes/Network/DI/NetworkModule.swift @@ -25,7 +25,10 @@ class NetworkModule: DependencyModule { cont.resolve() as MoyaLoggerPlugin]) } container.single(AwesomeAdsApiDataSourceType.self) { cont, _ in - MoyaAwesomeAdsApiDataSource(provider: cont.resolve(), environment: cont.resolve()) + MoyaAwesomeAdsApiDataSource(provider: cont.resolve(), + environment: cont.resolve(), + retryDelay: Constants.retryDelay, + logger: cont.resolve(param: MoyaAwesomeAdsApiDataSource.self) as LoggerType) } container.single(NetworkDataSourceType.self) { _, _ in AFNetworkDataSource() diff --git a/Pod/Classes/Network/DataSources/MoyaAwesomeAdsApiDataSource.swift b/Pod/Classes/Network/DataSources/MoyaAwesomeAdsApiDataSource.swift index 4b32fba9..d9927b51 100644 --- a/Pod/Classes/Network/DataSources/MoyaAwesomeAdsApiDataSource.swift +++ b/Pod/Classes/Network/DataSources/MoyaAwesomeAdsApiDataSource.swift @@ -11,10 +11,14 @@ class MoyaAwesomeAdsApiDataSource: AwesomeAdsApiDataSourceType { private let provider: MoyaProvider private let environment: Environment + private let retryDelay: TimeInterval + private let logger: LoggerType - init(provider: MoyaProvider, environment: Environment) { + init(provider: MoyaProvider, environment: Environment, retryDelay: TimeInterval, logger: LoggerType) { self.provider = provider self.environment = environment + self.retryDelay = retryDelay + self.logger = logger } func getAd(placementId: Int, query: QueryBundle, completion: @escaping OnResult) { @@ -107,18 +111,39 @@ class MoyaAwesomeAdsApiDataSource: AwesomeAdsApiDataSourceType { } private func responseHandler(target: AwesomeAdsTarget, completion: OnResult?) { - provider.request(target) { result in - switch result { - case .success(let response): - do { - _ = try response.filterSuccessfulStatusCodes() - completion?(Result.success(Void())) - } catch let error { - completion?(Result.failure(error)) + var retries = 0 + let delay = retryDelay + let innerLogger = logger + + func innerRequest() { + provider.request(target) { result in + switch result { + case .success(let response): + do { + _ = try response.filterSuccessfulStatusCodes() + completion?(Result.success(Void())) + } catch let error { + // If the server responds with a 4xx or 5xx error + completion?(Result.failure(error)) + } + case .failure(let error): + // This means there was a network failure + // - either the request wasn't sent (connectivity), + // - or no response was received (server timed out) + if retries < Constants.numberOfRetries { + innerLogger.error("Network failure, retrying again", error: error) + retries += 1 + DispatchQueue.global().asyncAfter(deadline: .now() + delay) { + innerRequest() + } + } else { + innerLogger.error("Number of retries reached", error: error) + completion?(Result.failure(error)) + } } - case .failure(let error): - completion?(Result.failure(error)) } } + + innerRequest() } } diff --git a/Pod/Classes/UI/Managed/SAManagedAdViewController.swift b/Pod/Classes/UI/Managed/SAManagedAdViewController.swift index 451623d3..be247b61 100644 --- a/Pod/Classes/UI/Managed/SAManagedAdViewController.swift +++ b/Pod/Classes/UI/Managed/SAManagedAdViewController.swift @@ -66,7 +66,7 @@ import WebKit private func configureCloseButton() { - if (closeButton != nil) { + if closeButton != nil { closeButton?.removeFromSuperview() closeButton = nil } @@ -161,7 +161,7 @@ extension SAManagedAdViewController: AdViewJavaScriptBridge { func onEvent(event: AdEvent) { callback?(placementId, event) - if (event == .adShown && config.closeButtonState == .visibleWithDelay) { + if event == .adShown && config.closeButtonState == .visibleWithDelay { showCloseButtonAfterDelay() }