Skip to content
This repository has been archived by the owner on Oct 23, 2024. It is now read-only.

feat(Network): Adds retry mechanism for the failed networking requests #278

Merged
merged 5 commits into from
Mar 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 0 additions & 51 deletions AFNetworkDataSource.swift

This file was deleted.

2 changes: 1 addition & 1 deletion Example/Shared/Networking/GetPlacements.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
19 changes: 0 additions & 19 deletions MoyaNetworkDataSource.swift

This file was deleted.

6 changes: 6 additions & 0 deletions Pod/Classes/Common/Model/Constants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 4 additions & 1 deletion Pod/Classes/Network/DI/NetworkModule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
47 changes: 36 additions & 11 deletions Pod/Classes/Network/DataSources/MoyaAwesomeAdsApiDataSource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,14 @@ class MoyaAwesomeAdsApiDataSource: AwesomeAdsApiDataSourceType {

private let provider: MoyaProvider<AwesomeAdsTarget>
private let environment: Environment
private let retryDelay: TimeInterval
private let logger: LoggerType

init(provider: MoyaProvider<AwesomeAdsTarget>, environment: Environment) {
init(provider: MoyaProvider<AwesomeAdsTarget>, 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<Ad>) {
Expand Down Expand Up @@ -107,18 +111,39 @@ class MoyaAwesomeAdsApiDataSource: AwesomeAdsApiDataSourceType {
}

private func responseHandler(target: AwesomeAdsTarget, completion: OnResult<Void>?) {
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
gunhansancar marked this conversation as resolved.
Show resolved Hide resolved
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()
}
gunhansancar marked this conversation as resolved.
Show resolved Hide resolved
} else {
innerLogger.error("Number of retries reached", error: error)
completion?(Result.failure(error))
}
}
case .failure(let error):
completion?(Result.failure(error))
}
}

innerRequest()
}
}
4 changes: 2 additions & 2 deletions Pod/Classes/UI/Managed/SAManagedAdViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ import WebKit

private func configureCloseButton() {

if (closeButton != nil) {
if closeButton != nil {
closeButton?.removeFromSuperview()
closeButton = nil
}
Expand Down Expand Up @@ -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()
}

Expand Down