Also, are there any plans to migrate eg. CoreBluetooth stack to new swift 6 concurrency?
I can’t talk about The Future™. If you’d like to see improvements in this space, I recommend that you file an enhancement request explaining what you’re doing, what’s causing you grief, and what you’d like to see change.
If you do file this, please post your bug number, just for the record.
I wonder if something has changed in this regards?
Yes and no. Integrating run loop based APIs clearly into a Swift 6 codebase is still quite tricky. I’ve spent a bunch of time playing around with that lately and my conclusion was… yeah… try to avoid that if you can |-:
There is one special case here, namely the main thread’s run loop. If you do all your run loop work on the main thread, things go relatively smoothly.
Whether that’s practical or not depends on the nature of your product. General Apple advice is to do as little as possible on the main {thread,queue,actor}. However, IMO that deserves some nuance. It’s fine to do coordination work on the main thread, but you need to avoid doing any heavy lifting. The classic example of this is HTTP networking with URLSession
. In most cases it’s fine to do the actual networking on the main thread, but if you end up downloading an image you need to make sure that it gets rendered on a secondary thread.
However, this isn’t universally true. If you’re building something where the main thread frame rate is absolutely critical — a game, perhaps, or maybe an drawing app that relies on Apple Pencil — then, yeah, you really do need to move everything off the main thread. That 8.3 ms frame period is a kicker.
When it comes to APIs that vend NSStream
subclasses, I have further advice.
First, some of those APIs have alternatives, and you should use them. For example, if you’re using CFSocketStream
, switch to Network framework.
Second, it’s possible to use streams from a Dispatch queue and that makes it easier to integrate with Swift concurrency. Specifically:
-
InputStream
and OutputStream
are Swift’s name for NSInputStream
and NSOutputStream
.
-
Those are toll-free bridged to CFReadStream
and CFWriteStream
.
-
You can use those on a Dispatch queue via CFReadStreamSetDispatchQueue
and CFWriteStreamSetDispatchQueue
.
-
Once you’re running on a Dispatch queue, you can use a custom executor to run do everything on an actor.
I have an example of that last point somewhere… OK, it’s here… AVCam Example: Can I use a Actor instead of a DispatchQueue for capture session activity?.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"