Skip to content

Commit ef033e8

Browse files
committed
Use associatedtypes to clean up URLSession conformance
1 parent a1af4aa commit ef033e8

File tree

4 files changed

+49
-4
lines changed

4 files changed

+49
-4
lines changed

Sources/Segment/Configuration.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ public class Configuration {
6767
var jsonNonConformingNumberStrategy: JSONSafeEncoder.NonConformingFloatEncodingStrategy = .zero
6868
var storageMode: StorageMode = .disk
6969
var anonymousIdGenerator: AnonymousIdGenerator = SegmentAnonymousId()
70+
var httpSession: (() -> any HTTPSession)? = nil
7071
}
7172

7273
internal var values: Values
@@ -245,8 +246,8 @@ public extension Configuration {
245246

246247
/// Specify a custom UserAgent string. This bypasses the OS dependent check entirely.
247248
@discardableResult
248-
func userAgent(_ userAgent: String) -> Configuration {
249-
values.userAgent = userAgent
249+
func httpSession(_ httpSession: @escaping @autoclosure () -> HTTPSession) -> Configuration {
250+
values.httpSession = httpSession
250251
return self
251252
}
252253

Sources/Segment/Utilities/HTTPClient.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ public enum HTTPClientErrors: Error {
2020
public class HTTPClient {
2121
private static let defaultAPIHost = "api.segment.io/v1"
2222
private static let defaultCDNHost = "cdn-settings.segment.com/v1"
23-
24-
internal var session: URLSession
23+
24+
internal var session: any HTTPSession
2525
private var apiHost: String
2626
private var apiKey: String
2727
private var cdnHost: String
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import Foundation
2+
3+
#if os(Linux) || os(Windows)
4+
import FoundationNetworking
5+
#endif
6+
7+
extension URLSessionDataTask: DataTask {}
8+
extension URLSessionUploadTask: UploadTask {}
9+
10+
// Give the built in `URLSession` conformance to HTTPSession so that it can easily be used
11+
extension URLSession: HTTPSession {}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import Foundation
2+
3+
#if os(Linux) || os(Windows)
4+
import FoundationNetworking
5+
#endif
6+
7+
public protocol DataTask {
8+
var state: URLSessionTask.State { get }
9+
func resume()
10+
}
11+
12+
public protocol UploadTask: DataTask {}
13+
14+
// An enumeration of default `HTTPSession` configurations to be used
15+
// This can be extended buy consumer to easily refer back to their configured session.
16+
public enum HTTPSessions {
17+
/// An implementation of `HTTPSession` backed by Apple's `URLSession`.
18+
public static func urlSession() -> any HTTPSession {
19+
let configuration = URLSessionConfiguration.ephemeral
20+
configuration.httpMaximumConnectionsPerHost = 2
21+
let session = URLSession(configuration: configuration, delegate: nil, delegateQueue: nil)
22+
return session
23+
}
24+
}
25+
26+
public protocol HTTPSession {
27+
associatedtype DataTaskType: DataTask
28+
associatedtype UploadTaskType: UploadTask
29+
30+
func uploadTask(with request: URLRequest, fromFile file: URL, completionHandler: @escaping @Sendable (Data?, URLResponse?, (any Error)?) -> Void) -> UploadTaskType
31+
func dataTask(with request: URLRequest, completionHandler: @escaping @Sendable (Data?, URLResponse?, (any Error)?) -> Void) -> DataTaskType
32+
func finishTasksAndInvalidate()
33+
}

0 commit comments

Comments
 (0)