-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create AuthenticatedURLSession and refactor code
- Loading branch information
1 parent
099c8e4
commit 857f41c
Showing
17 changed files
with
172 additions
and
109 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 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
32 changes: 0 additions & 32 deletions
32
AdRevenueWatch/Domain/Sources/Domain/GoogleAuth/UseCase/AccessTokenUseCase.swift
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
4 changes: 2 additions & 2 deletions
4
...tocol/AccessTokenRepositoryProtocol.swift → .../Domain/Network/AccessTokenProvider.swift
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
23 changes: 23 additions & 0 deletions
23
AdRevenueWatch/Domain/Sources/Domain/Network/AccessTokenUseCase.swift
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,23 @@ | ||
// | ||
// Created by Banghua Zhao on 03/10/2024 | ||
// Copyright Apps Bay Limited. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
|
||
public protocol AccessTokenUseCaseProtocol { | ||
var hasAccessToken: Bool { get } | ||
} | ||
|
||
public struct AccessTokenUseCase: AccessTokenUseCaseProtocol { | ||
private let accessTokenProvider: AccessTokenProvider | ||
|
||
public init(accessTokenProvider: AccessTokenProvider) { | ||
self.accessTokenProvider = accessTokenProvider | ||
} | ||
|
||
public var hasAccessToken: Bool { | ||
let accessToken = try? accessTokenProvider.getAccessToken() | ||
return accessToken != nil | ||
} | ||
} |
45 changes: 45 additions & 0 deletions
45
AdRevenueWatch/Domain/Sources/Domain/Network/NetworkError.swift
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,45 @@ | ||
// | ||
// Created by Banghua Zhao on 08/11/2024 | ||
// Copyright Apps Bay Limited. All rights reserved. | ||
// | ||
|
||
|
||
import Foundation | ||
|
||
public enum NetworkError: Error { | ||
case noAccessToken | ||
case accessTokenExpired // Access token expired | ||
case forbidden // User does not have permission | ||
case notFound // Resource not found (404) | ||
case serverError // Server error (5xx) | ||
case invalidResponse // Invalid or unexpected response | ||
case decodingError // JSON decoding failed | ||
case networkFailure // General network failure (e.g., no internet) | ||
case timeout // Request timed out | ||
case unknown // Unknown error | ||
|
||
// Provide a message for each error case | ||
public var message: String { | ||
switch self { | ||
case .noAccessToken: return "No access token" | ||
case .accessTokenExpired: | ||
return "Access token expired." | ||
case .forbidden: | ||
return "You don't have permission to access this resource." | ||
case .notFound: | ||
return "The requested resource was not found." | ||
case .serverError: | ||
return "The server encountered an error. Please try again later." | ||
case .invalidResponse: | ||
return "Received an invalid response from the server." | ||
case .decodingError: | ||
return "Failed to decode the data. Please try again." | ||
case .networkFailure: | ||
return "Network connection lost. Please check your internet connection." | ||
case .timeout: | ||
return "The request timed out. Please try again." | ||
case .unknown: | ||
return "An unknown error occurred. Please try again." | ||
} | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
AdRevenueWatch/Domain/Sources/Domain/Network/NetworkSession.swift
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,11 @@ | ||
// | ||
// Created by Banghua Zhao on 08/11/2024 | ||
// Copyright Apps Bay Limited. All rights reserved. | ||
// | ||
|
||
|
||
import Foundation | ||
|
||
public protocol NetworkSession { | ||
func data(for request: URLRequest) async throws -> (Data, URLResponse) | ||
} |
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
39 changes: 39 additions & 0 deletions
39
AdRevenueWatch/Repository/Sources/Repository/Network/AuthenticatedURLSession.swift
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,39 @@ | ||
// | ||
// Created by Banghua Zhao on 08/11/2024 | ||
// Copyright Apps Bay Limited. All rights reserved. | ||
// | ||
|
||
import Domain | ||
import Foundation | ||
|
||
public class AuthenticatedURLSession: NetworkSession { | ||
private let session: URLSession | ||
private let accessTokenProvider: AccessTokenProvider | ||
|
||
public init(session: URLSession = .shared, accessTokenProvider: AccessTokenProvider) { | ||
self.session = session | ||
self.accessTokenProvider = accessTokenProvider | ||
} | ||
|
||
public func data(for request: URLRequest) async throws -> (Data, URLResponse) { | ||
var authenticatedRequest = request | ||
|
||
// Inject the token into the request header if available | ||
if let token = try? accessTokenProvider.getAccessToken() { | ||
authenticatedRequest.addValue("Bearer \(token)", forHTTPHeaderField: "Authorization") | ||
} else { | ||
throw NetworkError.noAccessToken | ||
} | ||
|
||
// Perform the request | ||
let (data, response) = try await session.data(for: authenticatedRequest) | ||
|
||
// Handle 401 Unauthorized response | ||
if let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 401 { | ||
try accessTokenProvider.deleteAccessToken() | ||
throw NetworkError.accessTokenExpired | ||
} | ||
|
||
return (data, response) | ||
} | ||
} |
Oops, something went wrong.