Supporting concurrency in a library

Apologies if this has been discussed elsewhere.

If I have a library where I wish to support concurrency, then I can do:

  #if compiler(>=5.5) && canImport(_Concurrency)
    @available(iOS 15, tvOS 15, macOS 12, watchOS 8, *)
    public func myAsyncFunc() async { ... }
#endif

What is the best way to support both Xcode 13 (as above) and Xcode 13.2 where it's possible to lower the os version numbers?
I guess that I can do:

#if compiler(>=5.5.1) && canImport(_Concurrency)
?
#elseif compiler(>=5.5) && canImport(_Concurrency)
?
#endif

But do I then need to duplicate my implementation?

I would also be interested to know if there is a solution that does not involve code duplication.

For GRDB, due to those availability concerns, I chose to hide async apis until Swift 5.5.2 (Xcode 13.2+):

#if compiler(>=5.5.2) && canImport(_Concurrency)
@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
public func myAsyncFunc() async { ... }
#endif

Sendable conformances are exposed from Swift 5.5, though:

#if swift(>=5.5) && canImport(_Concurrency)
public typealias GRDBSendable = Swift.Sendable
#else
public typealias GRDBSendable = Any
#endif

public class MySendableClass: GRDBSendable { }

public class MyUncheckedSendableClass { }
#if swift(>=5.5) && canImport(_Concurrency)
extension MyUncheckedSendableClass: @unchecked Sendable { }
#endif

Note: the techniques were all inspired from guides/concurrency-adoption-guidelines.md at main · swift-server/guides · GitHub

4 Likes

Sadly no such solution exists.

This is what we've done in NIO as well.

3 Likes
Terms of Service

Privacy Policy

Cookie Policy