{"id":49873,"date":"2025-11-03T15:46:10","date_gmt":"2025-11-03T20:46:10","guid":{"rendered":"https:\/\/mjtsai.com\/blog\/?p=49873"},"modified":"2025-12-30T14:26:04","modified_gmt":"2025-12-30T19:26:04","slug":"swift-6-2-approachable-concurrency","status":"publish","type":"post","link":"https:\/\/mjtsai.com\/blog\/2025\/11\/03\/swift-6-2-approachable-concurrency\/","title":{"rendered":"Swift 6.2: Approachable Concurrency"},"content":{"rendered":"<p><a href=\"https:\/\/www.swift.org\/blog\/swift-6.2-released\/\">Holly Borla<\/a>:<\/p>\n<blockquote cite=\"https:\/\/www.swift.org\/blog\/swift-6.2-released\/\"><p>Swift 6.2 lowers the barrier to concurrent programming with a set of changes designed to reduce boilerplate and let you write safe concurrent code more naturally:<\/p><ul><li><strong>Single-threaded by default:<\/strong> Run your code on the main thread without explicit <code>@MainActor<\/code> annotations using the new option to isolate code to the main actor by default. This option is ideal for scripts, UI code, and other executable targets.<\/li><li><strong>Intuitive <code>async<\/code> functions:<\/strong> Write async code without concurrent access to mutable state. Previously, <code>nonisolated async<\/code> methods always switched to the global executor that manages the concurrent thread pool, which made it difficult to write async methods for class types without data-race safety errors. In Swift 6.2, you can migrate to an <a href=\"https:\/\/docs.swift.org\/compiler\/documentation\/diagnostics\/nonisolated-nonsending-by-default\/\">upcoming feature<\/a> where <code>async<\/code> functions run in the caller&rsquo;s execution context, even when called on the main actor.<\/li><li><strong>Opting into concurrency with <code>@concurrent<\/code>:<\/strong> Introduce code that runs concurrently using the new <code>@concurrent<\/code> attribute. This makes it clear when you want code to remain serialized on actor, and when code may run in parallel.<\/li><\/ul><\/blockquote>\n\n<p><a href=\"https:\/\/www.donnywals.com\/setting-default-actor-isolation-in-xcode-26\/\">Donny Wals<\/a>:<\/p>\n<blockquote cite=\"https:\/\/www.donnywals.com\/setting-default-actor-isolation-in-xcode-26\/\"><p>With <a href=\"https:\/\/www.donnywals.com\/exploring-concurrency-changes-in-swift-6-2\/\">Swift 6.2<\/a>, Apple has made a several improvements to Swift Concurrency and its approachability. One of the biggest changes is that new Xcode projects will now, by default, apply an implicit main actor annotation to all your code. This essentially makes your apps single-threaded by default.<\/p><p>I really like this change because without this change it was far too easy to accidentally introduce loads of concurrency in your apps.<\/p><p>In this post I&rsquo;d like to take a quick look at how you can control this setting as well as the setting for <code>nonisolated(nonsending)<\/code> from Xcode 26&rsquo;s build settings menu.<\/p><\/blockquote>\n\n<p><a href=\"https:\/\/www.donnywals.com\/what-is-approachable-concurrency-in-xcode-26\/\">Donny Wals<\/a>:<\/p>\n<blockquote cite=\"https:\/\/www.donnywals.com\/what-is-approachable-concurrency-in-xcode-26\/\"><p>Xcode 26 allows developers to opt-in to several of <a href=\"https:\/\/www.donnywals.com\/exploring-concurrency-changes-in-swift-6-2\/\">Swift 6.2&rsquo;s features<\/a> that will make concurrency more approachable to developers through a compiler setting called &ldquo;Approachable Concurrency&rdquo; or <code>SWIFT_APPROACHABLE_CONCURRENCY<\/code>. In this post, we&rsquo;ll take a look at how to enable approachable concurrency, and which compiler settings are affected \nby it.<\/p><\/blockquote>\n\n<p><a href=\"https:\/\/mastodon.social\/@mattiem\/115299937614208602\">Matt Massicotte<\/a>:<\/p>\n<blockquote cite=\"https:\/\/mastodon.social\/@mattiem\/115299937614208602\"><p>&ldquo;Approachable Concurrency&rdquo; is just a big group of settings. It is completely independent of making the default isolation MainActor.<\/p><\/blockquote>\n\n<p><a href=\"https:\/\/www.massicotte.org\/step-by-step-conforming-to-protocols\">Matt Massicotte<\/a>:<\/p>\n<blockquote cite=\"https:\/\/www.massicotte.org\/step-by-step-conforming-to-protocols\"><p>In the Swift 6 language mode, there are only <strong>two<\/strong> flags &ldquo;Approachable Concurrency&rdquo; changes: <code>InferIsolatedConformances<\/code> and <code>NonisolatedNonsendingByDefault<\/code>. It switches on more stuff in 5 mode, but those will not affect this material.<\/p><\/blockquote>\n\n<p><a href=\"https:\/\/www.hackingwithswift.com\/articles\/277\/whats-new-in-swift-6-2\">Paul Hudson<\/a> (<a href=\"https:\/\/mastodon.social\/@twostraws\/114479690308964815\">Mastodon<\/a>, <a href=\"https:\/\/news.ycombinator.com\/item?id=43940539\">Hacker News<\/a>):<\/p>\n<blockquote cite=\"https:\/\/www.hackingwithswift.com\/articles\/277\/whats-new-in-swift-6-2\"><p><a href=\"https:\/\/github.com\/swiftlang\/swift-evolution\/blob\/main\/proposals\/0466-control-default-actor-isolation.md\">SE-0466<\/a> introduces the ability for code to opt into running on a single actor by default &#x2013; to effectively go back to being a single-threaded program, where most code runs on the main actor until you say otherwise.<\/p><p>[&#8230;]<\/p><p><a href=\"https:\/\/github.com\/swiftlang\/swift-evolution\/blob\/main\/proposals\/0470-isolated-conformances.md\">SE-0470<\/a> resolves a small but important concurrency problem by making it possible to restrict a protocol conformance to a specific global actor.<\/p><p>[&#8230;]<\/p><p><a href=\"https:\/\/github.com\/swiftlang\/swift-evolution\/blob\/main\/proposals\/0472-task-start-synchronously-on-caller-context.md\">SE-0472<\/a> introduces a new way to create tasks so they start immediately if possible, rather than the existing behavior that only allows tasks to be queued to run at the next opportunity.<\/p><p>[&#8230;]<\/p><p><a href=\"https:\/\/github.com\/swiftlang\/swift-evolution\/blob\/main\/proposals\/0461-async-function-isolation.md\">SE-0461<\/a> adjusts the way nonisolated async functions are called so that they run on the same actor as their caller. This sounds like a really abstract change, but it is important so I would recommend you spend the time to understand what&rsquo;s changing and why.<\/p><p>[&#8230;]<\/p><p><a href=\"https:\/\/github.com\/swiftlang\/swift-evolution\/blob\/main\/proposals\/0371-isolated-synchronous-deinit.md\">SE-0371<\/a> introduces the ability to mark the deinitializers of actor-isolated classes as being isolated, which allows them to safely access data elsewhere in the class.<\/p><p>[&#8230;]<\/p><p><a href=\"https:\/\/github.com\/swiftlang\/swift-evolution\/blob\/main\/proposals\/0462-task-priority-escalation-apis.md\">SE-0462<\/a> introduces the ability for tasks to detect when their priority has been escalated, and also for us to manually escalate task priority if needed.<\/p><p>[&#8230;]<\/p><p><a href=\"https:\/\/github.com\/swiftlang\/swift-evolution\/blob\/main\/proposals\/0469-task-names.md\">SE-0469<\/a> introduces a useful change to the way we create tasks and child tasks: we can now give them <em>names<\/em>, which is ideal for debugging when one particular task goes rogue.<\/p><\/blockquote>\n\n<p><a href=\"https:\/\/www.massicotte.org\/default-isolation-swift-6_2\">Matt Massicotte<\/a>:<\/p>\n<blockquote cite=\"https:\/\/www.massicotte.org\/default-isolation-swift-6_2\">\n<p>As we started getting closer to the release of Swift 6.0, I had this bright idea. I decided to write about every evolution proposal related to concurrency that would ship with that release. This resulted in <a href=\"https:\/\/www.massicotte.org\/concurrency-swift-6-se-401\">12 posts<\/a> and let me tell you, it was a lot of work.<\/p>\n<p>[&#8230;]<\/p>\n<p>I don&rsquo;t think I can pull off a post for each proposal this year. But, I&rsquo;m not sure that&rsquo;s even necessary anyways. Many of them are minor things. But not all.<\/p>\n<p>[&#8230;]<\/p>\n<p>I wanted to go on this little side-quest because people don&rsquo;t find understanding <a href=\"https:\/\/www.massicotte.org\/isolation-intuition\">isolation<\/a> easy. Adding the distinction between static vs dynamic just makes it that much harder. And I really wanted to find a way to help explain this, because this is the Big Idea you need to get to understand what&rsquo;s changing.<\/p>\n<p>[&#8230;]<\/p>\n<p>Setting the default has the potential to completely remove the need to think about concurrency. This could be an <strong>enormous<\/strong> win in many situations. For example, it would make the Swift 6 language mode a more friendly choice for true beginner programmers.<\/p>\n<p>[&#8230;]<\/p>\n<p>Right now, though, I see myself sticking with a nonisolated default. I need more experience trying this out with real systems before I make up my mind.<\/p>\n<\/blockquote>\n\n<p><a href=\"https:\/\/mastodon.social\/@stroughtonsmith\/115151499676469637\">Steve Troughton-Smith<\/a>:<\/p>\n<blockquote cite=\"https:\/\/mastodon.social\/@stroughtonsmith\/115151499676469637\"><p>As I understand it, the whole point of Swift 6 is to add syntactic sugar all over your projects to try to codify ahead of time that you know which thread everything will run on. The &lsquo;approachable concurrency&rsquo; changes in 6.2 feels like an admission that <em>nobody is actually going to do that<\/em>, because it&rsquo;s too hard, if not impossible, for most apps. It&rsquo;s a major lift and a lot of work that, at best, leaves your app the same as before you started &#x1F605;<\/p><p>Approachable Concurrency, instead of making you annotate everything piece by piece, flips it and just assumes that none of your app is concurrent unless you specify otherwise, which is absolutely what should have been the default for Swift 6. If you were halfway through a Swift 6 port under the previous model, you now&#8230; delete all your code and go back to how it was before you annotated it?<\/p><\/blockquote>\n\n<p><a href=\"https:\/\/www.donnywals.com\/should-you-opt-in-to-swift-6-2s-main-actor-isolation\/\">Donny Wals<\/a>:<\/p>\n<blockquote cite=\"https:\/\/www.donnywals.com\/should-you-opt-in-to-swift-6-2s-main-actor-isolation\/\"><p>Finding the solution to the issues I describe above is pretty tedious, and it forces us to explicitly opt-out of concurrency for specific methods and eventually an entire class. This feels wrong. It feels like we&rsquo;re having to decrease the quality of our code just to make the compiler happy.<\/p><p>In reality, the default in Swift 6.1 and earlier was to introduce concurrency by default. Run as much as possible in parallel and things will be great.<\/p><p>This is almost never true. Concurrency is not the best default to have.<\/p><\/blockquote>\n\n<p><a href=\"https:\/\/mastodon.social\/@amyworrall\/115153828017655395\">Amy Worrall<\/a>:<\/p>\n<blockquote cite=\"https:\/\/mastodon.social\/@amyworrall\/115153828017655395\"><p>imo the thing they tried to make safe is not the thing that&rsquo;s actually the problem for most devs, and they did it in such a way that you can&rsquo;t make a halfway house solution. Especially when you&rsquo;re interacting with other people&rsquo;s code, sometimes there&rsquo;s just no way to architect things how you want.<\/p><\/blockquote>\n\n<p><a href=\"https:\/\/www.massicotte.org\/mistakes-with-concurrency\">Matt Massicotte<\/a>:<\/p>\n<blockquote cite=\"https:\/\/www.massicotte.org\/mistakes-with-concurrency\"><p>I do not think you need to go and read every proposal. I did, and honestly, it was a lot of <a href=\"concurrency-swift-6-se-401\">work<\/a>. But, something I learned from doing it is many of these new language features were specifically built to help <strong>hide<\/strong> details. It&rsquo;s still pretty early, but I think ultimately this is going to end up largely succeeding. What it all comes down to is how much concurrency you have in your project. (Probably too much)<\/p><p>You cannot progressively disclose the details of features you are <strong>actively<\/strong> using. Concurrency touches virtually all existing Swift code so tons of stuff gets shoved in your face all at once.<\/p><p>[&#8230;]<\/p><p>But, accidentally running stuff off the main thread is the simplest and most straight-forward concurrency problem you could possibly have it was <strong>absolutely pervasive<\/strong>.<\/p><p>[&#8230;]<\/p><p>Now there <strong>are<\/strong> some well-established <a href=\"https:\/\/inessential.com\/2014\/03\/08\/api_design_the_main_thread_and_queues.html\">patterns<\/a> that can help avoid many concurrency issues, that one definitely included. But, these are often employed by advanced users that have been practicing for years. I think it is easy for these habits to make &ldquo;I don&rsquo;t have this problem&rdquo; feel like &ldquo;this is not a problem&rdquo;.<\/p>\n<p>[&#8230;]<\/p>\n<p>Actors are not queues. Let me say it again, <code class=\"language-plaintext highlighter-rouge\">actor<\/code> is an advanced tool. Be wary of any material that makes it seem otherwise. You should be sticking to the binary main\/not-main until you are very comfortable with isolation before trying them out.<\/p><\/blockquote>\n\n<p><a href=\"https:\/\/news.ycombinator.com\/item?id=43942233\">travisgriggs<\/a> (<a href=\"https:\/\/mastodon.social\/@helge\/115489017584768824\">Helge He&szlig;<\/a>):<\/p>\n<blockquote cite=\"https:\/\/news.ycombinator.com\/item?id=43942233\"><p>One of the pitches in the earlier days was &ldquo;C\/Objective-C OK, but you can&rsquo;t write safe\/next level code with it&mdash;-Swift will close that gap.&rdquo;<\/p><p>N years later, it doesn&rsquo;t feel like there has been a step change in Apple software quality; if anything Apple software feels less solid, and looks cool &ldquo;look what I did&rdquo; extension points. I mean, some of the [things] you could do with runtime categories, and runtime prototypes were really cool. Now when I work on my 2 apps that originally happily port to Swift\/UIKit, I&rsquo;m just left confused with how to make things work. I&rsquo;m happy when it finally works, and don&rsquo;t ever try to improve the thing, it&rsquo;s too much work.<\/p><\/blockquote>\n\n<p><a href=\"https:\/\/mastodon.social\/@stroughtonsmith\/115148597927464330\">Steve Troughton-Smith<\/a>:<\/p>\n<blockquote cite=\"https:\/\/mastodon.social\/@stroughtonsmith\/115148597927464330\"><p>Swift 6 language mode is still a no-go, even with approachable concurrency turned on. I would be surprised if any full-featured UIKit app is able to use it, even now. Toy apps, or something that stays entirely within SwiftUI-land, maybe. It&rsquo;s a major lift.<\/p><\/blockquote>\n\n<p><a href=\"https:\/\/x.com\/jacobtechtavern\/status\/1964705574207070390\">Jacob Bartlett<\/a> (<a href=\"https:\/\/x.com\/ios_memes\/status\/1970088947058700668\">ios_memes<\/a>):<\/p>\n<blockquote cite=\"https:\/\/x.com\/jacobtechtavern\/status\/1964705574207070390\">\n<p>Is Swift 6 strict concurrency going to be our Python 3 moment?<\/p>\n<\/blockquote>\n\n<p><a href=\"https:\/\/mastodon.social\/@bigzaphod\/115152967149868341\">Sean Heber<\/a>:<\/p>\n<blockquote cite=\"https:\/\/mastodon.social\/@bigzaphod\/115152967149868341\"><p>So I now have Tapestry entirely compiling with Swift 6 mode.<\/p><p>That was&#8230; fun.<\/p><\/blockquote>\n\n<p><a href=\"https:\/\/mastodon.social\/@danielpunkass\/115274132644038204\">Daniel Jalkut<\/a>:<\/p>\n<blockquote cite=\"https:\/\/mastodon.social\/@danielpunkass\/115274132644038204\"><p>I achieved a major development milestone for my biggest app, MarsEdit, today. I can now build against Swift 6 with strict concurrency, and no warnings. It was harder than it should be (though Apple&rsquo;s working on that), but it feels good knowing I can move forward with concurrent confidence.<\/p><\/blockquote>\n\n<p><a href=\"https:\/\/hachyderm.io\/@groue\/115316825435142535\">Gwendal Rou&eacute;<\/a>:<\/p>\n<blockquote cite=\"https:\/\/hachyderm.io\/@groue\/115316825435142535\"><p>GRDB is in a strange bucket. I think it goes back to the introduction of Swift concurrency.<\/p><p>[&#8230;]<\/p><p>Want to use the new MainActor isolation by default? It&rsquo;s the default for new Xcode 26 projects, after all. Well this new language dialect creates incomprehensible compiler errors, and is so incompatible with the normal language that I&rsquo;m supposed to rewrite all sample codes and documentation (hint: I won&rsquo;t, SE-0466 is a sick joke).<\/p><p>Want to await SQLite with non-Sendable types? Well, I&rsquo;m not sure the language makes it possible to express that.<\/p><\/blockquote>\n\n<p><a href=\"https:\/\/mastodon.social\/@nicoreese\/115363334932073279\">Nico Reese<\/a> (<a href=\"https:\/\/forums.swift.org\/t\/defaultisolation-mainactor-and-core-data-background-tasks\/80569\">forum<\/a>):<\/p>\n<blockquote cite=\"https:\/\/mastodon.social\/@nicoreese\/115363334932073279\"><p>What would I do about this?<\/p><p>&ldquo;Main actor-isolated property &lsquo;timestamp&rsquo; can not be mutated from a Sendable closure&rdquo;<\/p><p>[&#8230;]<\/p><p>It seems to be an issue with Core Data not being 100% ready for these concurrency changes? The workaround gets rid of the warning but does not look very nice.<\/p><\/blockquote>\n\n<p><a href=\"https:\/\/mastodon.social\/@davedelong\/115232708520297931\">Dave DeLong<\/a>:<\/p>\n<blockquote cite=\"https:\/\/mastodon.social\/@davedelong\/115232708520297931\"><p>It&rsquo;s hard to look at the state of @swiftlang&rsquo;s concurrency model these days and draw any other conclusion than &ldquo;this is a hodge podge of conflicting models that are basically inoperable together&rdquo;.<\/p><p>IMO Swift Concurrency needs a huge &ldquo;reset&rdquo; button. Throw it all away and start over.<\/p><\/blockquote>\n\n<p><a href=\"https:\/\/mastodon.social\/@ryanashcraft\/115153072829870837\">Ryan Ashcraft<\/a>:<\/p>\n<blockquote cite=\"https:\/\/mastodon.social\/@ryanashcraft\/115153072829870837\">\n<p>All I want from Swift is a fast compiler that gives actually useful error messages. Enough syntax sugar. Oh and also, Swift Concurrency has been a disaster.<\/p>\n<\/blockquote>\n\n<p><a href=\"https:\/\/mister.computer\/@kyle\/115316893117389634\">Kyle Hughes<\/a>:<\/p>\n<blockquote cite=\"https:\/\/mister.computer\/@kyle\/115316893117389634\"><p>It doesn&rsquo;t feel like any plane has been landed in the realm of Apple platform development since the introduction of SwiftUI in 2019. Nothing new introduced fits well together. Everything that is released feels unfinished and gets informally deprecated, only to be replaced with another incomplete solution. It&rsquo;s a confusing moment to be in&mdash;we will likely reflect on this as the time where we should have known what direction we were headed in.<\/p><p>Modern Apple platform development is optimized for building miniature versions of Apple&rsquo;s own apps or for tackling interesting programming-language puzzles. It is, at present, poorly suited to making strategic, long-term decisions about economically viable software&mdash;or to providing the tools needed to make such decisions.<\/p><p>That gap will either get solved or not, but regardless, the end of this narrative arc is likely in the air right now.<\/p><\/blockquote>\n\n<p>Previously:<\/p>\n<ul>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2025\/10\/29\/swift-6-2\/\">Swift 6.2<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2025\/08\/07\/sendable-unchecked-sendable-sendable-sending-and-nonsending\/\">Sendable, @unchecked Sendable, @Sendable, sending, and nonsending<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2025\/08\/06\/xcode-26-beta-5\/\">Xcode 26 Beta 5<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2025\/06\/13\/wwdc-2025-links\/\">WWDC 2025 Links<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2025\/03\/14\/rewriting-the-typescript-compiler-in-go\/\">Rewriting the TypeScript Compiler in Go<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2025\/03\/03\/swift-6-1\/\">Swift 6.1<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2025\/02\/04\/swift-concurrency-glossary\/\">Swift Concurrency Glossary<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2024\/12\/20\/swift-concurrency-in-real-apps\/\">Swift Concurrency in Real Apps<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2024\/11\/26\/watch-out-for-counterintuitive-implicit-actor-isolation\/\">Watch Out for Counterintuitive Implicit Actor-Isolation<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2024\/11\/25\/swift-vision-improving-the-approachability-of-data-race-safety\/\">Swift Vision: Improving the Approachability of Data-Race Safety<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2024\/11\/18\/swift-concurrency-proposal-index\/\">Swift Concurrency Proposal Index<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2024\/09\/19\/swift-6\/\">Swift 6<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2024\/06\/04\/swift-at-10\/\">Swift at 10<\/a><\/li>\n<\/ul>\n\n<p id=\"swift-6-2-approachable-concurrency-update-2025-11-04\">Update (<a href=\"#swift-6-2-approachable-concurrency-update-2025-11-04\">2025-11-04<\/a>): <a href=\"https:\/\/mastodon.social\/@helge\/115488680611714758\">Helge He&szlig;<\/a>:<\/p>\n<blockquote cite=\"https:\/\/mastodon.social\/@helge\/115488680611714758\"><p>If you actually understand concurrency, you don&rsquo;t need all the boilerplate &#x1F62C;\nI think, like with static typing, the key idea is to help people who <em>don&rsquo;t<\/em> understand it. And like the former it mostly fails those promises.<\/p><p>It&rsquo;s like driving with training wheels.<\/p><p>Also that the static checks guarantee valid concurrent code is a huge misconception. Like static typing it just removes a small, mostly irrelevant, class\nof errors.<\/p><\/blockquote>\n\n<p><a href=\"https:\/\/ds9soft.com\/blog\/2025\/09\/exited-mac-development\/\">Sebasti&aacute;n Ben&iacute;tez<\/a>:<\/p>\n<blockquote cite=\"https:\/\/ds9soft.com\/blog\/2025\/09\/exited-mac-development\/\"><p>The walled garden, as it is called, has a door through which the users can easily exit if they find they don&rsquo;t want it anymore. But for a Mac exclusive developer, it&rsquo;s a prison. There is no way out other than escaping.<\/p><p>[&#8230;]<\/p><p>Yes, [Swift is] great for some things, such as\nmodelling data and has some nice FP in it. But then you have to deal with async\nfunctions (colouring) invading all your code, and all the troubles they bring with so\nmuch concurrency. That has to be one of the reasons Apple now provides an\noption to make everything @MainActor.<\/p><p>It&rsquo;s becoming bloated and complex. At the same time, the standard library is\nlacking, compared to C++ at least.<\/p><p>Macro implementation is horrible, period. I&rsquo;m a lisper, so I have a high bar. There is\nno way Swift macros are as useable as Common Lisp&rsquo;s macros. I gave up just\nlooking at the documentation on how to implement one.<\/p><p>One last thing about it: so much evolution, so many changes, lack of directed\ndesign, makes all code constantly obsolete, bit-rotting. You are pushed to adopt\nnew language features, newer frameworks, since they are updated with the new\nfeatures, so your hand is sometimes forced. Then there comes all the refactoring\nor you are left behind.<\/p><\/blockquote>\n\n<p>Previously:<\/p>\n<ul>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2025\/09\/04\/writing-mac-and-ios-apps-shouldnt-be-so-difficult\/\">Writing Mac and iOS Apps Shouldn&rsquo;t Be So Difficult<\/a><\/li>\n<\/ul>\n\n<p id=\"swift-6-2-approachable-concurrency-update-2025-12-22\">Update (<a href=\"#swift-6-2-approachable-concurrency-update-2025-12-22\">2025-12-22<\/a>): <a href=\"https:\/\/mastodon.social\/@obrhoff\/115741317997150365\">Dennis Oberhoff<\/a>:<\/p>\n<blockquote cite=\"https:\/\/mastodon.social\/@obrhoff\/115741317997150365\">\n<p>Looking at several projects I&rsquo;ve come across recently, I have serious doubts that a largescale transition to Swift 6 is going to happen.<\/p><p>Many teams are still producing large amounts of legacy code that does not take Swift 6 into consideration at all.<\/p><p>This trend seems to be further reinforced by LLMs (that still often generate singletons) and by engineers who simply want to get the job done.<\/p><p>Are we stuck?<\/p>\n<\/blockquote>\n\n<p><a href=\"https:\/\/mastodon.social\/@helge\/115744823218571487\">Helge He&szlig;<\/a>:<\/p>\n<blockquote cite=\"https:\/\/mastodon.social\/@helge\/115744823218571487\">\n<p>There is another potential outcome people here won&rsquo;t like: Instead of transitioning to Swift 6, a transition to Flutter, RN and the likes.<\/p>\n<p>This is often a big discussion point in projects and 6 might be the final nail in the coffin &#8230;<\/p>\n<\/blockquote>\n\n<p><a href=\"https:\/\/mastodon.social\/@helge\/115748324514855877\">Helge He&szlig;<\/a>:<\/p>\n<blockquote cite=\"https:\/\/mastodon.social\/@helge\/115748324514855877\">\n<p>I sometimes have the feeling that too much thought is put into dealing with multithreading issues. My impression is that async is actually much harder to deal with conceptually. Regardless whether you have a thread pool or whether it all runs on a single thread, like in JavaScript (or Swift Wasm?).<\/p>\n<p>I find it quite easy to fit a few serial threads\/queues into my brain and coordinate them. And rather hard to digest an arbitrary graph of concurrent tasks.<\/p>\n<\/blockquote>\n\n<p id=\"swift-6-2-approachable-concurrency-update-2025-12-23\">Update (<a href=\"#swift-6-2-approachable-concurrency-update-2025-12-23\">2025-12-23<\/a>): <a href=\"https:\/\/fuckingapproachableswiftconcurrency.com\/en\/\">Pedro Pi&ntilde;era<\/a> (<a href=\"https:\/\/x.com\/pepicrft\/status\/2003192155045589261\">tweet<\/a>):<\/p>\n<blockquote cite=\"https:\/\/fuckingapproachableswiftconcurrency.com\/en\/\">\n<p>Finally understand async\/await, actors, and Sendable. Clear mental models, no jargon.<\/p>\n<\/blockquote>\n\n<p id=\"swift-6-2-approachable-concurrency-update-2025-12-30\">Update (<a href=\"#swift-6-2-approachable-concurrency-update-2025-12-30\">2025-12-30<\/a>): See also: <a href=\"https:\/\/news.ycombinator.com\/item?id=46432916\">Hacker News<\/a>.<\/p>","protected":false},"excerpt":{"rendered":"<p>Holly Borla: Swift 6.2 lowers the barrier to concurrent programming with a set of changes designed to reduce boilerplate and let you write safe concurrent code more naturally:Single-threaded by default: Run your code on the main thread without explicit @MainActor annotations using the new option to isolate code to the main actor by default. This [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"apple_news_api_created_at":"2025-11-03T20:46:13Z","apple_news_api_id":"5e5dee3b-f91f-4f95-b6d1-60d4b38efde3","apple_news_api_modified_at":"2025-12-30T19:26:13Z","apple_news_api_revision":"AAAAAAAAAAAAAAAAAAAABg==","apple_news_api_share_url":"https:\/\/apple.news\/AXl3uO_kfT5W20WDUs4794w","apple_news_coverimage":0,"apple_news_coverimage_caption":"","apple_news_is_hidden":false,"apple_news_is_paid":false,"apple_news_is_preview":false,"apple_news_is_sponsored":false,"apple_news_maturity_rating":"","apple_news_metadata":"\"\"","apple_news_pullquote":"","apple_news_pullquote_position":"","apple_news_slug":"","apple_news_sections":"\"\"","apple_news_suppress_video_url":false,"apple_news_use_image_component":false,"footnotes":""},"categories":[4],"tags":[109,1412,31,2741,46,30,2742,71,2200,901],"class_list":["post-49873","post","type-post","status-publish","format-standard","hentry","category-programming-category","tag-coredata","tag-grdb","tag-ios","tag-ios-26","tag-languagedesign","tag-mac","tag-macos-tahoe-26","tag-programming","tag-swift-concurrency","tag-swift-programming-language"],"apple_news_notices":[],"_links":{"self":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/49873","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/comments?post=49873"}],"version-history":[{"count":8,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/49873\/revisions"}],"predecessor-version":[{"id":50597,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/49873\/revisions\/50597"}],"wp:attachment":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/media?parent=49873"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/categories?post=49873"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/tags?post=49873"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}