Skip to content

Commit 0aec20e

Browse files
committed
Add a default client for simple usage
1 parent 999ab08 commit 0aec20e

File tree

7 files changed

+58
-22
lines changed

7 files changed

+58
-22
lines changed

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,7 @@ This creates a simple GET request to `https://www.google.com/test/cats/images`.
5757
You can also compose and override requests:
5858

5959
```swift
60-
@Request
61-
struct TestRequest {
60+
@Request struct TestRequest {
6261
@Header var test: String {
6362
return "Computed"
6463
}

Sources/NetworkingClient/ClientMacro.swift

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,19 @@ import Foundation
1313
/// adding the necessary ``NetworkClient`` conformance.
1414
///
1515
/// ```
16-
/// @Client
17-
/// struct MyClient {
18-
/// var command: Session {
19-
/// Session()
20-
/// .onRequest { request, session in
21-
/// // handle request creation
22-
/// return request
23-
/// }.enableLogs()
24-
/// .validate(for: [.accepted, .ok])
25-
/// .retryPolicy(.doNotRetry)
16+
/// @Client struct MyClient {
17+
/// var session: Session {
18+
/// Session {
19+
/// URLSessionConfiguration.default
20+
/// .timeoutIntervalForRequest(60)
21+
/// .timeoutIntervalForResource(120)
22+
/// .requestCachePolicy(.useProtocolCachePolicy)
23+
/// }.onRequest { request, task, session, configurations in
24+
/// // handle request creation
25+
/// return request
26+
/// }.enableLogs()
27+
/// .validate(for: [.accepted, .ok])
28+
/// .doNotRetry()
2629
/// }
2730
/// }
2831
/// ```

Sources/NetworkingClient/Configurations/Configurable+Extension.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ extension Configurable {
1919
/// Use this method to attach a custom ``StatusValidator``.
2020
///
2121
/// - Parameter validator: The validator to apply.
22-
public func validate(_ validator: some StatusValidator) -> Self {
22+
public func validate(using validator: some StatusValidator) -> Self {
2323
return configuration(\.statusValidator, validator)
2424
}
2525

@@ -43,7 +43,7 @@ extension Configurable {
4343
validStatuses: statuses,
4444
handler
4545
)
46-
return validate(validator)
46+
return validate(using: validator)
4747
}
4848

4949
/// Sets the handler used to control how responses are cached.
@@ -119,7 +119,7 @@ extension Configurable {
119119
///
120120
/// Use this method to apply a custom retry strategy using a type
121121
/// that conforms to ``RetryInterceptor``.
122-
public func retry(_ interceptor: some RetryInterceptor) -> Self {
122+
public func retry(using interceptor: some RetryInterceptor) -> Self {
123123
return configuration(\.retryPolicy, interceptor)
124124
}
125125

@@ -152,7 +152,7 @@ extension Configurable {
152152
strategy: strategy,
153153
handler: handler
154154
)
155-
return retry(interceptor)
155+
return retry(using: interceptor)
156156
}
157157

158158
/// Sets the retry policy with a fixed delay between attempts.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//
2+
// DefaultClient.swift
3+
// Networking
4+
//
5+
// Created by Joe Maghzal on 25/07/2025.
6+
//
7+
8+
import Foundation
9+
10+
/// The default networking client provided by the framework.
11+
///
12+
/// `DefaultClient` offers a preconfigured session with sensible settings for most apps,
13+
/// including standard timeouts, automatic retry for transient errors, and HTTP status validation.
14+
///
15+
/// Use this client when you don’t need advanced customization or want a quick start.
16+
///
17+
/// You can override any part of the session configuration if needed.
18+
@Client public struct DefaultClient {
19+
/// The default session used by the client.
20+
public var session: Session {
21+
Session {
22+
URLSessionConfiguration.default
23+
.timeoutIntervalForRequest(60)
24+
.timeoutIntervalForResource(120)
25+
.requestCachePolicy(.useProtocolCachePolicy)
26+
}.retry(using: DefaultRetryInterceptor())
27+
.validate(using: DefaultStatusValidator())
28+
}
29+
}
30+
31+
public enum Networking {
32+
/// The default networking client for simple bootstrapping.
33+
public static let client = DefaultClient()
34+
}

Sources/NetworkingClient/Session/NetworkClient.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import NetworkingCore
1212
/// Requirements for defining network clients that handle session management
1313
/// and perform network requests, such as data tasks and download tasks.
1414
/// It provides an abstraction for the session and commands network requests based on that session.
15-
public protocol NetworkClient: Configurable {
15+
public protocol NetworkClient: Configurable, Sendable {
1616
/// The internal session command that is used to execute network requests.
1717
var _session: Session! {get set}
1818

Sources/NetworkingClient/Utilities/URLSessionConfiguration+Extension.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,12 @@ extension URLSessionConfiguration {
6666

6767
/// Sets additional HTTP headers for the session configuration.
6868
///
69-
/// - Parameter headers: The headers to be added.
69+
/// - Parameter header: The headers to be added.
7070
/// - Returns: The modified ``URLSessionConfiguration``.
7171
public func headers(
72-
@HeadersBuilder headers: () -> some RequestHeader
72+
@HeadersBuilder header: () -> some RequestHeader
7373
) -> Self {
74-
httpAdditionalHeaders = headers().headers
74+
httpAdditionalHeaders = header().headers
7575
return self
7676
}
7777
}

Tests/NetworkingClientTests/Configurations/ClientConfigurationsTests.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ struct ClientConfigurableTests {
4141

4242
do {
4343
let interceptor = DummyRetryInterceptor()
44-
let configured = TestConfigurable().retry(interceptor)
44+
let configured = TestConfigurable().retry(using: interceptor)
4545
#expect(configured.configurationValues.retryPolicy is DummyRetryInterceptor)
4646
}
4747

@@ -81,7 +81,7 @@ struct ClientConfigurableTests {
8181
@Test func statusValidatorConfiguration() {
8282
do {
8383
let validator = DummyStatusValidator()
84-
let configured = TestConfigurable().validate(validator)
84+
let configured = TestConfigurable().validate(using: validator)
8585
#expect(configured.configurationValues.statusValidator is DummyStatusValidator)
8686
}
8787

0 commit comments

Comments
 (0)