-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Joe Maghzal
committed
Feb 5, 2023
1 parent
7cadc18
commit b546f28
Showing
19 changed files
with
942 additions
and
250 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// | ||
// File.swift | ||
// | ||
// | ||
// Created by Joe Maghzal on 11/13/22. | ||
// | ||
|
||
import Foundation | ||
|
||
extension Network { | ||
internal static func errorBuilder<T: EndPoint, Model: Decodable, ErrorModel: Error & Decodable>(call: NetworkCall<Model, ErrorModel, T>, error: Error) async throws -> Model { | ||
if call.handler.withLoading { | ||
await NetworkData.shared.set(loading: false) | ||
} | ||
switch call.policy { | ||
case .never: | ||
guard call.handler.withError, configurations.errorLayer.shouldDisplay(error) else { | ||
throw error | ||
} | ||
if let networkError = error as? NetworkError { | ||
NetworkData.shared.error = networkError | ||
}else { | ||
NetworkData.shared.error = NetworkError(title: "Something went wrong!", body: error.localizedDescription) | ||
} | ||
throw error | ||
case .always: | ||
let retryCount = call.endPoint.retryCount ?? configurations.retryCount | ||
let currentCount = NetworkData.shared.retries[call.endPoint.id.description] ?? 0 | ||
guard retryCount > currentCount, configurations.errorLayer.shouldRetry(error) else { | ||
throw error | ||
} | ||
return try await call.get() | ||
case .custom(let number): | ||
let currentCount = NetworkData.shared.retries[call.endPoint.id.description] ?? 0 | ||
guard number > currentCount, configurations.errorLayer.shouldRetry(error) else { | ||
throw error | ||
} | ||
return try await call.get() | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
// | ||
// NetworkCall.swift | ||
// | ||
// | ||
// Created by Joe Maghzal on 05/02/2023. | ||
// | ||
|
||
import Foundation | ||
|
||
public struct NetworkCall<Model: Decodable, ErrorModel: Error & Decodable, Route: EndPoint> { | ||
//MARK: - Properties | ||
internal var handler = NetworkHandler.all | ||
internal var resultModel: Model.Type? | ||
internal var errorModel: ErrorModel.Type? | ||
internal var endPoint: Route | ||
internal var validCode: ((ResponseStatus) throws -> Bool)? | ||
internal var map: ((ResponseStatus) throws -> Model)? | ||
internal var policy = NetworkRetries.always | ||
} | ||
|
||
//MARK: - Modifiers | ||
public extension NetworkCall { | ||
func tryDecode<T: Decodable>(using type: T.Type) -> NetworkCall<T, ErrorModel, Route> { | ||
return NetworkCall<T, ErrorModel, Route>(handler: handler, resultModel: type, errorModel: errorModel, endPoint: endPoint, validCode: validCode, map: nil, policy: policy) | ||
} | ||
func tryCatch<T: Error & Decodable>(using type: T.Type) -> NetworkCall<Model, T, Route> { | ||
return NetworkCall<Model, T, Route>(handler: handler, resultModel: resultModel, errorModel: type, endPoint: endPoint, validCode: validCode, map: map, policy: policy) | ||
} | ||
func handling(_ handler: NetworkHandler) -> Self { | ||
return NetworkCall(handler: handler, resultModel: resultModel, errorModel: errorModel, endPoint: endPoint, validCode: validCode, map: map, policy: policy) | ||
} | ||
func validate(_ transform: @escaping (ResponseStatus) throws -> Bool) rethrows -> Self { | ||
return NetworkCall(handler: handler, resultModel: resultModel, errorModel: errorModel, endPoint: endPoint, validCode: transform, map: map, policy: policy) | ||
} | ||
func retryPolicy(_ policy: NetworkRetries) -> Self { | ||
return NetworkCall(handler: handler, resultModel: resultModel, errorModel: errorModel, endPoint: endPoint, validCode: validCode, map: map, policy: policy) | ||
} | ||
func map<T: Decodable>(_ transform: @escaping (ResponseStatus) throws -> T) rethrows -> NetworkCall<T, ErrorModel, Route> { | ||
return NetworkCall<T, ErrorModel, Route>(handler: handler, resultModel: nil, errorModel: errorModel, endPoint: endPoint, validCode: validCode, map: transform, policy: policy) | ||
} | ||
func get() async throws -> Model { | ||
return try await Network.request(call: self) | ||
} | ||
func task() async throws -> Task<Model, Error> { | ||
return Task { () -> Model in | ||
try await get() | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// | ||
// File.swift | ||
// | ||
// | ||
// Created by Joe Maghzal on 05/02/2023. | ||
// | ||
|
||
import Foundation | ||
|
||
extension Network { | ||
nonisolated internal static func request<T: EndPoint, Model: Decodable, ErrorModel: Error & Decodable>(call: NetworkCall<Model, ErrorModel, T>) async throws -> Model { | ||
do { | ||
NetworkData.shared.add(call.endPoint.id.description) | ||
let request = try requestBuilder(endPoint: call.endPoint) | ||
if call.handler.withLoading { | ||
await NetworkData.shared.set(loading: true) | ||
} | ||
let networkResult = try await URLSession.shared.data(for: request) | ||
guard !Task.isCancelled else { | ||
throw NetworkError.cancelled | ||
} | ||
let status = ResponseStatus(statusCode: (networkResult.1 as? HTTPURLResponse)?.statusCode ?? 0) | ||
if let validity = call.validCode, !(try validity(status)) { | ||
throw NetworkError.unnaceptable(status: status) | ||
} | ||
if let map = call.map { | ||
return try map(status) | ||
} | ||
return try await resultBuilder(call: call, request: request, data: networkResult.0) | ||
}catch { | ||
return try await errorBuilder(call: call, error: error) | ||
} | ||
} | ||
nonisolated public static func request<T: EndPoint>(for endPoint: T) async throws -> NetworkCall<EmptyData, EmptyData, T> { | ||
return NetworkCall(endPoint: endPoint) | ||
} | ||
} |
Oops, something went wrong.