Skip to content

Commit

Permalink
0.38.0
Browse files Browse the repository at this point in the history
  • Loading branch information
dankinsoid committed Mar 10, 2024
1 parent 6650640 commit 4c35352
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 44 deletions.
28 changes: 10 additions & 18 deletions Example/Sources/PetStore/PetStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,16 @@ public struct PetStore {

var client: NetworkClient

public init(baseURL: BaseURL, fileID: String, line: UInt) {
client = NetworkClient(baseURL: baseURL.url)
.fileIDLine(fileID: fileID, line: line)
.bodyDecoder(PetStoreDecoder())
.bearerAuth(
valueFor(
live: UserDefaultsTokenCacheService(),
test: MockTokenCacheService()
)
)
.httpClientMiddleware(
.tokenRefresher {
try await $0.client.path("token").get()
} auth: {
.bearer(token: $0)
}
)
}
public init(baseURL: BaseURL, fileID: String, line: UInt) {
client = NetworkClient(baseURL: baseURL.url)
.fileIDLine(fileID: fileID, line: line)
.bodyDecoder(PetStoreDecoder())
.tokenRefresher { client, _ in
try await client.path("token").post()
} auth: {
.bearer(token: $0)
}
}
}

// MARK: - "pet" path
Expand Down
2 changes: 0 additions & 2 deletions Example/Sources/PetStore/TokenRefresher.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,9 @@ extension NetworkClient {
struct APITokenRefresher: TokenRefresher {

let tokenService: TokenCacheService
let client: NetworkClient

init(_ configs: NetworkClient.Configs) {
tokenService = configs.tokenCacheService
client = configs.client
}

private let tokenRefreshStatusCode = 401 // Status code indicating the token needs to be refreshed
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ import PackageDescription
let package = Package(
name: "SomeProject",
dependencies: [
.package(url: "https://github.com/dankinsoid/swift-networking.git", from: "0.37.0")
.package(url: "https://github.com/dankinsoid/swift-networking.git", from: "0.38.0")
],
targets: [
.target(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,31 @@ public extension HTTPClientMiddleware where Self == TokenRefresherMiddleware {
}
}

extension NetworkClient {

public func tokenRefresher(
cacheService: TokenCacheService = valueFor(live: .keychain, test: .mock),
expiredStatusCodes: Set<HTTPStatusCode> = [.unauthorized],
refreshToken: @escaping (NetworkClient, NetworkClient.Configs) async throws -> String,
auth: @escaping (String) -> AuthModifier
) -> Self {
httpClientMiddleware(
TokenRefresherMiddleware(
cacheService: cacheService,
expiredStatusCodes: expiredStatusCodes,
refreshToken: { try await refreshToken(self, $0) },
auth: auth
)
)
}
}

public struct TokenRefresherMiddleware: HTTPClientMiddleware {

let tokenCacheService: TokenCacheService
let expiredStatusCodes: Set<HTTPStatusCode>
let auth: (String) -> AuthModifier
let refreshToken: (NetworkClient.Configs) async throws -> String
private let tokenCacheService: TokenCacheService
private let expiredStatusCodes: Set<HTTPStatusCode>
private let auth: (String) -> AuthModifier
private let refreshToken: (NetworkClient.Configs) async throws -> String

public init(
cacheService: TokenCacheService,
Expand Down
6 changes: 3 additions & 3 deletions Sources/SwiftNetworking/NetworkClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ public struct NetworkClient {
/// - Rethrows: Rethrows any errors encountered within the closure.
/// - Returns: The result of the closure of type `T`.
public func withConfigs<T>(_ operation: (Configs) throws -> T) rethrows -> T {
var configs = Configs(createRequest: _createRequest)
var configs = Configs()
modifyConfigs(&configs)
return try operation(configs)
}
Expand All @@ -135,13 +135,13 @@ public struct NetworkClient {
/// - Rethrows: Rethrows any errors encountered within the closure.
/// - Returns: The result of the closure of type `T`.
public func withConfigs<T>(_ operation: (Configs) async throws -> T) async rethrows -> T {
var configs = Configs(createRequest: _createRequest)
var configs = Configs()
modifyConfigs(&configs)
return try await operation(configs)
}

private func createRequest() throws -> (URLRequest, Configs) {
var configs = Configs(createRequest: _createRequest)
var configs = Configs()
modifyConfigs(&configs)
return try (_createRequest(configs), configs)
}
Expand Down
11 changes: 1 addition & 10 deletions Sources/SwiftNetworking/NetworkClientConfigs.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,9 @@ public extension NetworkClient {
struct Configs {

private var values: [PartialKeyPath<NetworkClient.Configs>: Any] = [:]
private let createRequest: (Configs) throws -> URLRequest

/// Initializes a new configuration set for `NetworkClient`.
public init(
createRequest: @escaping (Configs) throws -> URLRequest
) {
self.createRequest = createRequest
}

/// The network client used for network operations.
public var client: NetworkClient {
NetworkClient(createRequest: createRequest).configs(\.self, self)
public init() {
}

/// Provides subscript access to configuration values based on their key paths.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ final class HTTPResponseValidatorTests: XCTestCase {
let validator = HTTPResponseValidator.statusCode(200 ... 299)
let response = HTTPURLResponse(url: URL(string: "https://example.com")!, statusCode: 200, httpVersion: nil, headerFields: nil)!
let data = Data()
let configs = NetworkClient.Configs { _ in
URLRequest(url: URL(string: "https://example.com")!)
}
let configs = NetworkClient.Configs()

// Validation should pass for a status code within the range
XCTAssertNoThrow(try validator.validate(response, data, configs))
Expand All @@ -27,9 +25,7 @@ final class HTTPResponseValidatorTests: XCTestCase {
let validator = HTTPResponseValidator.alwaysSuccess
let response = HTTPURLResponse(url: URL(string: "https://example.com")!, statusCode: 200, httpVersion: nil, headerFields: nil)!
let data = Data()
let configs = NetworkClient.Configs { _ in
URLRequest(url: URL(string: "https://example.com")!)
}
let configs = NetworkClient.Configs()

// Validation should always pass without throwing any errors
XCTAssertNoThrow(try validator.validate(response, data, configs))
Expand Down

0 comments on commit 4c35352

Please sign in to comment.