(Some) Unanswered Swift Group Questions
(Some) Unanswered Swift Group Questions
June 10, 2026
There was a great Swift Group Lab session recently. And this follows a similar concurrency-specific session which was also wonderful. I think the format is a little challenging for the panelists, but they manage to do a great job regardless. It's so valuable to have real questions answered by the people that built the stuff. And I happen to really enjoy the live, unscripted discussion.
(I was also just delighted to hear the entire panel discussing the utility of non-Sendable types!)
However!
There's a voting system. And that means a number of questions weren't selected. This time I copied those down and I thought it could be fun to take a shot at answering the ones that are more in my area.
Why is the default for a new project Swift 5 in Xcode 27? Should we immediately be changing this to Swift 6 for new projects, or stick with the defaults?
My guess is because there are parts of Apple's SDK that are still quite difficult to use in Swift 6 mode. It absolutely can be done, but some areas will demand significant understanding.
Here's the core question - do you understand what the Swift 6 language mode actually does? I have seen quite a few people turn it on and then get very surprised when crashes start happening because of dynamic actor isolation enforcement.
New projects can be a great time to start digging into this area. But it really depends on your goals. I think it is quite risky to make use of concurrency features with the compiler feedback totally disabled, so the defaults aren't great. But, you really do need to understand your project settings to make sure you are making reasonable choices. They can be extremely consequential.
Can you help me better understand @preconcurrency ? I had to add this before import MusicKit in my app in order for it to build in Swift 6. Does this mean that particular framework is not using the latest concurrency features? Does using this annotation make my app "unsafe"?
In fact, I've written a whole thing on it!
A preconcurency import does not necessarily mean unsafe. What it means is more like "This library is missing annotations, but I'm using it correctly". If that is actually the case, nothing is unsafe. Or at least, not any more unsafe than it was before. However, it does open the door for more accidental mistakes because it is suppressing compiler checking for the entire file. I much prefer targeted opt-outs like nonisolated(unsafe) when possible. But all of these facilities do reduce the amount of compile-time checking that can happen.
(I'm also not familiar with MusicKit specifically, but casually checking, it does look like it has at least some concurrency support today. Perhaps that @preconcurrency import is no longer necessary as of the 27 SDK?)
What's your recommendation on the default actor isolation for Swift apps? Should we try to always use MainActor isolation or would you recommend to use nonisolated for fresh code bases?
Apple's defacto recommendation for new app targets is default MainActor, because that's what the Xcode template does.
In my experience, this mode can be very challenging to use, even for small projects. I'm not saying you should not try it. But it typically demands that you understand the concurrency system more deeply than with a default of nonisolated. I would be careful here, particularly if you do not feel very comfortable with concurrency.
For a func that is not marked as @MainActor, non-isolated or @concurrent explicitly, does the thread get assigned at calling site OR is it by default bg thread?
My interpretation of the question is that it is less about the effects of concurrency annotations themselves, and more about the relationship between static isolation and threads. Because you have to remember that all functions have a well-defined static isolation. As worded, this question rules out like 90% of all functions.
The only functions that are guaranteed to not end up on a background thread are those marked @MainActor.
The only situation where the callsite could matter is for nonisolated functions. And the NonisolatedNonsendingByDefault setting (AKA "Approachable Concurrency") will play an important role here and will influence a more complete answer.
Especially as we move towards a world where NonisolatedNonsendingByDefault is just the way, you should be thinking about nonisolated functions as running in the calling context. All other functions do not.
with migration to swift 6 on a large project and moving to approachable concurrency and @MainActor default isolation we end up having data models or enums that belong to the core data layer of the app be @MainActor isolated which is confusion based on separation of concepts<br>how to handle it ?
Very long story short: you probably need to make them explicitly nonisolated or move them into a nonisolated-default module. Many types do not make sense to be MainActor,...