You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Problem
I ran into a problem migrating code to Swift 6., because the compiler cannot be certain that OIDServiceConfiguration is used in a thread safe manner.
Consider the following function:
func discoverConfiguration(discoveryUrl: URL) async throws -> OIDServiceConfiguration {
try await withCheckedThrowingContinuation { continuation in
OIDAuthorizationService.discoverConfiguration(forDiscoveryURL: discoveryUrl) { config, _ in
if let config {
continuation.resume(returning: config) // Error: Sending 'config' risks causing data races
// Task-isolated 'config' is passed as a 'sending' parameter; Uses in callee may race with later task-isolated uses
} else {
// ...
}
}
}
}
Because OIDServiceConfiguration is returned via callback closure, the compiler has to assume that it may be used by the sending function (+[OIDAuthorizationService discoverConfiguration]) even after the closure is called. Because OIDServiceConfiguration is not declared Sendable this results in a compile error (see inline comments).
Solution
Annotate OIDServiceConfiguration with NS_SWIFT_SENDABLE.
This makes the assumption that OIDServiceConfiguration is in fact thread safe. Looking at the code, I see only one point which might make the class not thread safe: OIDServiceConfiguration holds a reference to OIDServiceDiscovery which in turn holds a reference to NSDictionary (NSDictionary *_discoveryDictionary) which may contain non thread safe objects. But in real life those would only be PODs (String, Int) which are thread safe, correct?
Ideally, all thread safe types in AppAuth would be annotated with NS_SWIFT_SENDABLE.
Workaround
Wrap the OIDServiceConfiguration object into an @unchecked Sendable object to send it to the continuation. This disables the compiler checks.
Additional Information
No compile error with Swift 5 – not even with complete concurrency checks enabled.
The text was updated successfully, but these errors were encountered:
Problem
I ran into a problem migrating code to Swift 6., because the compiler cannot be certain that
OIDServiceConfiguration
is used in a thread safe manner.Consider the following function:
Because
OIDServiceConfiguration
is returned via callback closure, the compiler has to assume that it may be used by the sending function (+[OIDAuthorizationService discoverConfiguration]
) even after the closure is called. BecauseOIDServiceConfiguration
is not declaredSendable
this results in a compile error (see inline comments).Solution
Annotate
OIDServiceConfiguration
withNS_SWIFT_SENDABLE
.This makes the assumption that
OIDServiceConfiguration
is in fact thread safe. Looking at the code, I see only one point which might make the class not thread safe:OIDServiceConfiguration
holds a reference toOIDServiceDiscovery
which in turn holds a reference toNSDictionary
(NSDictionary *_discoveryDictionary
) which may contain non thread safe objects. But in real life those would only be PODs (String, Int) which are thread safe, correct?Ideally, all thread safe types in AppAuth would be annotated with
NS_SWIFT_SENDABLE
.Workaround
Wrap the
OIDServiceConfiguration
object into an@unchecked Sendable
object to send it to the continuation. This disables the compiler checks.Additional Information
No compile error with Swift 5 – not even with complete concurrency checks enabled.
The text was updated successfully, but these errors were encountered: