3 Commits

Author SHA1 Message Date
a659a9399c Merge pull request 'Update LCEssentials+API.swift' (#8) from fix/api/mainactor-session-hang into main
Reviewed-on: #8
2026-07-07 13:21:09 -03:00
Daniel Arantes Loverde
03044604fd Update LCEssentials+API.swift 2026-07-07 13:15:45 -03:00
Daniel Arantes Loverde
2c781fbac6 Update LCEssentials+API.swift 2026-06-06 11:00:08 -03:00

View File

@@ -28,7 +28,6 @@ import Security
#if canImport(UIKit)
import UIKit
#endif
#endif
/// A generic `Result` enumeration to represent either a success `Value` or a failure `Error`.
public enum Result<Value, Error: Swift.Error> {
@@ -195,14 +194,31 @@ public struct API {
API.requestLOG(method: method, request: request)
}
let session = URLSession(
configuration: .default,
delegate: URLSessionDelegateHandler(
certData: API.certData,
password: API.certPassword
),
delegateQueue: nil
)
// Only spin up a dedicated session (with its own @MainActor
// delegate hop for every TLS/auth challenge) when client
// certificate auth is actually configured. Creating one of
// these per request unconditionally and never invalidating
// it could stall the async challenge callback waiting on an
// already-busy MainActor, hanging the request indefinitely with
// no timeout or error ever surfacing. The common case (no
// client cert) uses the shared session, which has none of this
// risk and is what URLSession is designed to be reused as.
let usesCertSession = API.certData != nil
let session: URLSession = usesCertSession
? URLSession(
configuration: .default,
delegate: URLSessionDelegateHandler(
certData: API.certData,
password: API.certPassword
),
delegateQueue: nil
)
: URLSession.shared
defer {
if usesCertSession {
session.finishTasksAndInvalidate()
}
}
do {
let (data, response) = try await session.data(for: request)