❌

Reading view

Xcode 27

Apple (xip, downloads):

Xcode 27 includes Swift 6.4 and SDKs for iOS 27, iPadOS 27, tvOS 27, watchOS 27, macOS 27, and visionOS 27. Xcode 27 supports on-device debugging in iOS 17 and later, tvOS 17 and later, watchOS 10 and later, and visionOS. Xcode 27 requires a Mac running macOS Tahoe 26.6 or later.

Peter Witham:

Is this new in Xcode 27? Pretty sure it as and I approve whole heartedly! I really hate setting up Xcode settings more than once.

Christian Beer:

Building with Xcode 27 doesn’t work because of some intransparent XCStrings error… and I even can’t check with Xcode 26 anymore because Apple decided to not let me run it on macOS 27…

Steven Woolgar:

After all these years Apple has finally broken cmd-e in Xcode 27.

Previously:

  •  

SwiftUI Toolbars

Natalia Panferova:

I thought it would be useful to have a single reference for the different ways we can style the toolbar in SwiftUI on macOS 26.

Phil Zakharchenko:

The toolbar id creates a stable customization domain, and each item id gives the framework something stable to persist when the user adds, removes, or reorders controls. This identifiability of toolbar items is a requirement for customization. Under the hood, when SwiftUI inevitably bridges your toolbar contents to NSToolbar, these identifiers will be directly translated to the NSToolbarItem’s itemIdentifiers.

As we continue the migration to a customizable toolbar, we are likely to encounter a few surprises related to this model.

[…]

After a closer inspection, and perhaps a few minutes of digging through the documentation, we come to the bleak realization: there is no customizable ToolbarItemGroup API.

[…]

The regular toolbar model and the customizable toolbar model overlap, but they are not interchangeable. You cannot give a ToolbarItemGroup an id, and you cannot place one directly inside toolbar(id:content:).

Majid Jabrayilov:

Let’s take a look at another example. This one is a bit tricky, because on macOS, you will get Action 1 in the top trailing position and the whole group of actions centered in the navigation bar. On iOS, you will get Action 1 pinned to trailing and all other items collapsed.

[…]

The final addition to the Toolbar API is the toolbarMinimizeBehavior view modifier allowing us to minimize toolbars while scrolling up or down. You can minimize tab, bottom, window and navigation bars with it.

With new modifiers SwiftUI gives us a much better balance between system-driven adaptation and explicit control. We can now decide which actions are more important, which items should always stay visible, which groups should intentionally live in the overflow menu, and how toolbars should react to scrolling.

Natalia Panferova:

iOS 27 includes a few smaller additions that make toolbar content easier to configure.

We can remove the default padding around an item whose content should extend to its edges with contentMarginsRemoved(_:)[…]

[…]

The status bar is now represented by ToolbarPlacement.statusBar, so its visibility can be controlled through the same toolbar API as other bars[…]

[…]

ForEach now conforms to ToolbarContent, which means we can generate toolbar items directly from a collection[…]

Natascha Fadeeva:

Together, the toolbar APIs let us express the importance of each action while SwiftUI continues to handle the toolbar’s layout across different sizes.

Previously:

  •  

TipKit for the Real World

Craig Hockenberry:

Then, when you look at the sample code, it’s all SwiftUI. At least the sample compiles and runs because it uses a completely different syntax than what was shown at WWDC.

[…]

Eventually I stumbled upon TipUIPopoverViewController which inherits from UIViewController. That should work! […] But it didn’t: the close button on the popover didn’t work.

[…]

Until you realize that any changes you make are stored in a SQLite database, debugging is very confusing. It’s also easy for your own state to get out-of-sync with the Tip state: there is not a single source of truth.

[…]

Unfortunately, that sample code doesn’t scale well. If you have a view with multiple tips, you’re going to be littering your code with tip instances, observation tasks, and popover controllers. It’s a mess and a clear sign that the TipKit developers didn’t think much about UIKit.

Fatbobman:

In the previous article, we introduced the basic usage of TipKit. In this article, we will discuss some advanced topics related to TipKit, such as how to fully customize Tip views (not using TipView and popoverTip), how to use TipKit with UIKit, and how TipKit can share data across different applications, as well as how to reuse Tip declaration code. Additionally, we will attempt to address some common questions and concerns about TipKit.

Previously:

  •  

Swift 6.4: Warning for Weak Captures Within Nested Closures

John Sundell:

New in Swift 6.4 […] is a warning which is emitted when a nested closure performs a weak capture while the parent closure implicitly captures that object as a strong reference.

At first glance, that new diagnostic could be a bit puzzling, since it might seem unnecessary to have to specify such a weak capture twice (or, alternatively, move it to the parent closure’s capture list), but it turns out that it’s an incredibly useful new warning that can help us avoid a quite common kind of memory management bug.

[…]

Finally, in situations where capturing self strongly doesn’t actually lead to a retain cycle, we can silence the new warning for nested weak captures by explicitly adding self to the outer closure’s capture list, such as when creating a Task within the following example[…]

Previously:

  •  

Ending the Golden Era for Backward-Compatible Apps

Matthias Gansrigler-Hrad:

I don’t appreciate being forced by Xcode 27 to drop support for macOS 10.13-11.0. It’s my decision which OSes I want to support, not Apple’s. Yes, I can keep Xcode 26 around until submissions require Xcode 27, but what then?

Originally, Xcode 27 was documented as supporting Big Sur on Intel Macs, but now the earliest is Monterey.

I’m frustrated, too, but it’s more honest than the recent releases that claimed to support deployment on older macOS versions when Apple clearly hadn’t tested that it actually worked. I filed bugs, and Apple kept responding that they’d fixed it, when they hadn’t.

Using old versions of Xcode isn’t a great solution because they aren’t supported on Golden Gate. Swift also makes it more difficult to call newer APIs when using an older SDK. You can’t just copy/paste a method prototype or constant value and conditionally use it when running on a newer OS.

Ighor July:

I eventually found a hidden workaround that changes the errors back into warnings. That is good news, but it does not make the concern disappear. The setting is undocumented, absent from the normal Xcode interface, and currently being tested only in a beta toolchain. The larger question is what Apple intends to enforce when Xcode 27 is final and, later, when App Store submission requirements move to its SDKs.

[…]

Apple’s current Xcode system requirements list Xcode 26 with deployment targets beginning at iOS 15 and macOS 11. Yet developers have been able to enter older targets manually. In an Apple Developer Forums discussion about Xcode 26, an Apple product manager explained that the published deployment target range is aligned with simulator support and on-device debugging. The accepted answer confirms that an iOS 13 target can still build even though it falls below the range in Apple’s table.

My own tests went further. Xcode 26.5 compiled a project targeting iOS 9.0. It warned that the target was older than the supported range, but the build succeeded. On macOS, I have compiled current apps with deployment targets as old as macOS 10.9. Xcode warned me, but it still produced working applications.

[…]

For iOS and iPadOS, staying on Xcode 26 is not a lasting option. Apple has repeatedly made a current Xcode and SDK mandatory for new App Store submissions. […] If any one of those conditions fails, iOS and iPadOS developers will have no normal App Store path for publishing new updates that still support versions older than 15.

Previously:

Update (2026-09-07): Léo Natan:

Just want to remind you guys that if you move to Xcode 27, the only “officially” supported and sanction Xcode for GG, UIDesignRequiresCompatibility is no longer respected across the 27 OSes (apps built with older Xcodes still are). So you might suddenly find out you have a lot of work ahead of you, adding support for the dreaded Glass. And 27 Glass is not the same as 26 Glass. That can be an issue if you skipped 26 altogether but still want to support it.

Previously:

Update (2026-09-11): Nick Lockwood:

I mostly ignored the Xcode 27 betas (mainly due to the barely-usable Device Hub) so I didn’t realize the passive-aggressive prompts to drop support for iOS < 15 that you get when submitting apps is being backed up by Xcode 27 refusing to compile apps at all unless you bump the deployment target 😧

  •  

EagleFiler 1.9.21

EagleFiler 1.9.21 is a maintenance release of my Mac digital filing cabinet and e-mail archiving app. It can now capture the selected messages from MailMaven, including all their metadata, and can link back to the original message. The capture key now works with the Helium browser, and importing from Mariner Paperless and Microsoft Outlook is improved as well.

  • There was an interesting regression caused by the fact that macOS now implements pop-up menus using separate windows (NSPopupMenuWindow) that post their own notifications for becoming key and for resigning key status.

  • Encrypted libraries need to be converted to APFS, since a future version of macOS will drop support for CoreStorage. You can do this now, or it’s possible that we’ll be able to offer an automatic converter in a future version.

  • There were more problems with PyObjC importing symbols, this time generic Swift classes that have angle brackets in their names. I had previously added more precise imports to skip over these symbols, which aren’t needed anyway, so it’s a mystery why a few users were still seeing this problem despite using the same macOS versions as everyone else. In any case, I adjusted the PyObjC importer to hopefully avoid problems with all such symbols, even if Apple adds more in future versions.

  • macOS Tahoe introduced a bug displaying custom folder icons, which was finally fixed in macOS 26.4.1.

Previously:

  •  

SpamSieve 3.3.1

SpamSieve 3.3.1 is an update of my Mac e-mail spam filter that improves the filtering accuracy and includes various optimizations, fixes, and updates for macOS 27. Some interesting engineering issues were:

  • I’m still supporting macOS 10.13, but the app can now build with the macOS 12 deployment target in preparation for Xcode 27. The way Swift handles calling deprecated APIs remains annoying. You need workarounds like protocols to suppress a warning in a particular region of code. Often, I am updating to a newer API, but I want to continue using the old one on earlier versions of macOS. Right now I am heavily testing on macOS 26, so I would like to only deploy the new code there. Sometimes the initial versions of APIs are buggy, and I don’t want to have to retest every feature on every version. But Swift doesn’t like me to gate the calls to macOS 26 and later if the new API was actually introduced in, say, macOS 11.

  • The most risky update was probably switching to the Swift API for Scanner. This is tricky because the current scan position changes from being based on UTF-16 indexes to String.Index. And in some cases my code was intentionally scanning into the middle of a combining character. I was really glad to have extensive tests here.

  • Recent versions of Tahoe introduced a Core Data bug that broke save recovery (when invalid Unicode can’t be written to the database and we have to fix it up first). When the error comes in, SpamSieve looks under the NSDetailedErrorsKey key, but the value of this key is "NSDetailedErrorsKey" while the actual error info is under the key "NSDetailedErrors".

  • Database corruption combined with a Core Data bug and two Swift behaviors were causing crashes. The root problem, I think, is that in this situation Core Data neglects to set the error pointer for -[NSManagedObjectContext countForFetchRequest:error:]. Normally, Swift would detect this and throw a generic nilError. However, this method signals errors by returning NSNotFound instead of nil. It’s annotated as swift_error(nonnull_error), which I think means that Swift doesn’t even look at the return value, only the (unset) error. So my code was receiving NSNotFound on the non-error path, treating it as a real count, and doing some math with it, which (by default in Swift) leads to a crash if there’s overflow. Now my code checks for NSNotFound and uses Int.addingReportingOverflow().

  • I reimplemented Core Data batch fetching because of two problems with the fetchBatchSize option. First, it logs spurious errors when fetching from multiple stores at once. Second, it leads to high memory use. It will load objects in batches, but it never releases the earlier batches. You can manually refault objects that you no longer need, but it will still hold onto the full object shells, which can add up. My implementation only holds onto IDs, and it can fetch the IDs using a different context than the objects to push more work to background threads.

  • I’m now using String.makeContiguousUTF8() in various places to avoid slow iteration of bridged strings.

  • There was a regression where some menu code could crash on macOS 10.13. -[NSMenu setItemArray:] is only available on macOS 10.14 and later, whereas the getter is always available. With old Objective-C, the two methods could be annotated with separate availabilities. The Objective-C property syntax doesn’t allow this, so there’s no way for the compiler to flag calls where the setter is missing.

  • The AppleScript support works much better with large data sets. The key, I think, is to never return an array to Cocoa for a scripting property/element. First, if you give it a lazy array it will sometimes try to access all the elements even if it only needs a few. And, second, AppleScript will run out of memory if the array is too large. By using indexed accessors, you can maintain laziness and only convert one object to a descriptor at a time. By caching a batch-fetching collection, you can limit the number of fetches and respond quickly when AppleScript requests individual objects.

Previously:

  •  

Swift Package Index Joins Apple

Ted Kremenek, Dave Verwer, and Sven A. Schmidt (Hacker News):

Bringing Swift Package Index to Apple allows us to build on its strong foundations while preserving its vision and expertise. Together, we’re building a comprehensive package registry to serve the Swift community’s evolving needs.

[…]

Swift Package Index will continue to operate as it does today. You can continue to rely on it to discover packages, check compatibility, and explore documentation. As we embark on this new phase, our goal is to accelerate development and introduce new features that make discovering and evaluating packages even better.

[…]

Swift Package Index will remain open source.

Helge Heß:

A little sad that this era ends. SPI was a stronghold of Apple independence, a package index run by independent and trusted individuals.

  •  

Swift 6.4

Swift 6.4 is now available in beta form with Xcode 27. The Swift Evolution proposals are listed here.

What’s new in Swift:

Discover the latest language advancements, including updates for everyday ergonomics, improved concurrency, and safer high-performance code. Explore workflow and language interoperability improvements and updates in embedded Swift.

Build real-time apps and services with gRPC and Swift:

Build engaging live experiences with gRPC in your Swift app and backend. gRPC is an open-source RPC framework designed for high-performance, bidirectional streaming APIs. Explore how the gRPC Swift package provides a modern, safe runtime built with Swift concurrency.

Explore numerical computing in Swift with MLX:

Bring NumPy-style computing natively to Swift with MLX Swift. Discover how to eliminate cross-language friction in your machine learning workflows by handling image processing, tensor operations, and neural network training in a single, type-safe environment. Explore the APIs that let you leverage GPU acceleration while enjoying the compiler, tooling, and debugging experience you already know.

Swift Group Lab:

Join us online for a deep dive into WWDC26 with Apple engineers and designers to ask questions, get advice, and follow the discussion about the week’s biggest Swift announcements.

Matt Massicotte:

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.

Xcode 27 Beta 2 Release Notes:

The Swift dependency scanner has been optimized to avoid redundant setup work and header searches when looking up Clang modules during a single dependency-scan action, substantially improving scanning performance.

As a consequence of this change, every Clang module reachable from a single Swift dependency-scan action must have a unique module name. If two module maps visible to the same scan declare a Clang module with the same name, the scan may report an error.

[…]

System now provides Swift APIs for the C stat, lstat, fstat, and fstatat system calls. This includes a new Stat type with initializers from FilePath, FileDescriptor, or a C string; FilePath.stat() and FileDescriptor.stat() instance methods; and supporting types (FileType, FileMode, FileFlags, UserID, GroupID, DeviceID, and Inode).

Wade Tregaskis:

The final piece of the Prospective Vision for Accessors, this allows for more efficient accessors on structs, in a nutshell.

[…]

Now there’s a safer version of the existing withUnsafeTemporaryAllocation (first introduced in Swift 5.6). It works just like you’d expect. It comes in both “raw bytes” and typed elements versions, just like its unsafe predecessor.

[…]

The new isTriviallyIdentical(to:) method offers a guaranteed-fast way to check two objects for equality. It is essentially an optimised version of the existing equality condition provided by Equatable and the == operator. It’s useful because it guarantees O(1) time complexity, whereas == makes no formal guarantees at all (and for many types is O(N) or worse). But unlike the existing identity comparison operator === – also O(1) – it promises to do more than just tell if two objects are the exact same pointer, and it works on value types (not just reference types).

[…]

These new types generalise the existing patterns of borrowed and mutable references, that have previously existed in Swift in much more restricted forms (e.g. inout parameters are essentially MutableRef parameters, and Span & MutableSpan are array equivalents).

There’s now a built-in function for demangling Swift symbol names, in the Runtime module (that’s bundled with the Swift toolchain, alongside the stdlib etc).

Khoa Pham:

As Apple has aligned OS version numbers across platforms, Swift 6.4 takes the next step by letting you collapse repetitive availability attributes into a single anyAppleOS token.

[…]

There are situations where you need to call a deprecated API while you plan a migration, or audit a critical function for unsafe usage, without letting those concerns bleed into the rest of the project. The new @diagnose attribute handles both cases.

[…]

Some work should complete even after a task is cancelled, like flushing a file to avoid corruption. withTaskCancellationShield wraps a region where Task.isCancelled always returns false.

Antoine van der Lee:

Swift 6.4 implements SE-0493: Support async calls in defer bodies. This is one of those changes that feels obvious once you need it.

[…]

Swift 6.4 improves error handling for unstructured tasks through SE-0520: Discardable result use in Task initializers. The change helps you catch a subtle bug: creating a throwing task and then ignoring its returned task handle.

[…]

Swift 6.4 also implements SE-0530: Async Result Support.

[…]

Swift 6.4 implements SE-0518: ~Sendable for explicitly marking non-Sendable types. It allows you to communicate that a type has been audited and should not conform to Sendable.

Slava Pestov:

I thought it would be a good time to detail some of the type checker performance improvements we worked on since I shared the type checker performance roadmap last year. I’m also going to outline a couple of things we plan on looking at next.

Previously:

Update (2026-07-09): I was optimistic about improvements to the type checker making compilation faster, but I found that compiling my predominantly Swift project with Xcode 27 Beta 3 was only 0.3% faster than with Xcode 26.6. I wonder if there’s some extra setting I’m supposed to enable.

  •  

Swift 6.3

Holly Borla and Joe Heck (Hacker News):

Swift 6.3 introduces the @c attribute, which lets you expose Swift functions and enums to C code in your project. […] @c also works together with @implementation. This lets you provide a Swift implementation for a function declared in a C header[…]

[…]

Swift 6.3 introduces module selectors to specify which imported module Swift should look in for an API used in your code. If you import more than one module that provides API with the same name, module selectors let you disambiguate which API to use[…]

[…]

Provide pre-specialized implementations of a generic API for common concrete types using @specialize.

[…]

Guarantee inlining — a compiler optimization that expands the body of a function at the call-site — for direct calls to a function with @inline(always).

[…]

Expose the implementation of a function in an ABI-stable library to clients with @export(implementation). This allows the function to participate in more compiler optimizations.

The Swift Evolution proposals are listed here.

Florian Pircher:

I love that I can now name my module the same as the primary/only type of the module without making the module namespace unreachable.

Jordan Rose:

Congrats to my Swift colleagues for #finally pushing @c over the finish line! Been a long time coming.

Previously:

  •  

SwiftData in appleOS 27

SwiftData updates:

Section your query results by creating your query with a macro that takes a sectionBy parameter, as listed on the Additional query macros page.

Use types that conform to Codable in a model, including types you don’t control directly, by using the codable option for Schema.Attribute.

Receive real-time updates to models that match specified fetch criteria by using the ResultsObserver type.

Observe remote model changes with the HistoryObserver type.

What’s new in SwiftData:

Discover the latest enhancements to SwiftData. We’ll show you how to persist custom and third-party types using Codable, and group fetched data into sections in your SwiftUI app. We’ll also explore how to observe data store changes anywhere else using ResultsObserver and HistoryObserver, giving you the flexibility to drive powerful state objects and react precisely to model updates.

Again, there seems to be nothing new in Core Data this year, nor any communication about it. There’s still no interoperability for object IDs. The SwiftData changes seem fine but don’t really address the new framework’s deficiencies relative to Core Data. It seems like there are still basic problems with threading. I just don’t understand how Apple is deciding what to prioritize with this framework.

With SwiftUI, the bones seem questionable, but at least we can see that Apple is full steam ahead, with substantial progress to address limitations and pain points. SwiftData seemed to have better bones and is much less ambitious. Getting it right seemed like just a matter of follow through. But, for some inexplicable reason, it seems to lack the resources and/or urgency to reach its potential. And even though SwiftUI is clearly the chosen one, AppKit remains in development. Meanwhile, Core Data seems to be abandoned, even though SwiftData feels more like a side quest than a genuine attempt to supplant it.

The implicit message, for those who have build the core of their app on top of Apple’s old persistence framework, seems to be that Apple is not looking out for their needs. Core Data will surely get maintenance to the extent that Apple’s own apps need it, but there’s no evidence of a future or even a migration plan. The answer, I guess, is third-party frameworks, but that’s not an easy migration, either, since none is even as close a match as SwiftData.

Add persistence with SwiftData:

Experience SwiftData in action as we add persistence to an existing app. We’ll show you how to define your data models and seamlessly integrate persistent data with SwiftUI. You’ll also learn foundational skills for managing your app’s state using this expressive, declarative API.

SwiftData Group Lab:

Join us online for a deep dive into WWDC26 with Apple engineers and designers to ask questions, get advice, and follow the discussion about the week’s biggest SwiftData announcements.

macOS Golden Gate 27 Beta Release Notes:

Fixed: You might experience a deadlock for @Query when saving a ModelContext on a background actor while scheduling new async tasks for a ModelActor.

Paul Hudson:

I am so pleased to say these words: IT IS A BIG YEAR FOR SWIFTDATA! 🎉

Mohammad Azam:

SwiftData predicates can now work directly with enum values, resulting in cleaner models and simpler query code.

[…]

In iOS 27, Apple introduced support for compound predicates through the Predicate(all:) and Predicate(any:) initializers, making it easier to build queries dynamically based on user input.

I’m not sure why that took so long.

The framework is gradually moving beyond simple demos and becoming easier to use in larger, more sophisticated projects.

[…]

iOS 27 is the first release where many of the framework’s early rough edges have started to disappear.

Matt Massicotte:

Results of my now-yearly check to see if SwiftData’s ModelActor continues to sometimes run code on the main thread: yes it does

Fatbobman:

Compared with @Query gaining support for section fetches, and ResultsObserver enabling observation of query result changes outside views, I am more interested in @Attribute(.codable). It provides a clearer storage intent and gives developers a way to avoid falling into the black box of composition.

Of course, @Attribute(.codable) is not a silver bullet. It is more like a clearly defined escape hatch SwiftData provides for opaque Codable types: suitable for storing external types that you cannot model yourself, but still genuinely need to persist. The cost is that this content cannot participate in SwiftData’s predicate, sort, or migration awareness. Precisely for this reason, its value lies not in being “more powerful,” but in being “more explicit.”

However, SwiftData still does not provide cloud syncing for public / shared data, nor have I seen a clearer signal of performance improvements. These issues will continue to limit its adoption. For many developers, SwiftData this year feels more like it is filling key gaps rather than making a leap significant enough to fundamentally change confidence in it.

Helge Heß:

Codable types in SwiftData seem pretty lame given that SQLite absolutely does have JSON support and does support queries on it?

But the funnier thing in the MKMapItem.Identifier example is that MKMapItem.Identifier is a RawRepresentable==String, so it could actually be stored as a String in the store.

Previously:

  •  

SwiftUI in appleOS 27

macOS Golden Gate 27 Beta Release Notes:

AsyncImage now automatically caches downloaded images using HTTP caching protocols, allowing servers to control caching behavior via standard headers.

[…]

Xcode 27 introduces a new @State implementation that avoids this repeated evaluation. This new behavior back-deploys to iOS 17 aligned OSes. The new @State is implemented with a Swift macro. It is largely source compatible with the property wrapper version, with a few exceptions.

[…]

Text views now support TextRenderer.

[…]

In apps built with the 27.0 SDKs, the new ReadableDocument and WritableDocument protocols support asynchronous reading and writing, progress reporting, and direct access to document URLs. New DocumentGroup initializers that adopt these protocols let you disable document creation for editing-only apps and present custom UI before any document is opened.

[…]

TextField respects custom font and color styling applied to its prompt.

[…]

List accepts drops in two cases that previously didn’t work: drags with compatible transfer representations are accepted into reorderable content even when the .reorderableItem transfer type isn’t present, and a .dropDestination(…) modifier declared on a list item now performs the drop.

SwiftUI updates:

Build your project in Xcode 27 or later to construct type-agnostic content from closures that you mark with ContentBuilder, which serves as the unified replacement for type-specific builders like ToolbarContentBuilder and CommandsBuilder.

Add reordering by drag-and-drop in containers such as lists, stacks, grids, or custom layouts with reorderable() and reorderContainer(for:isEnabled:move:).

Add custom swipe actions to views in containers such as scroll views, stacks, grids, or custom layouts using swipeActions(edge:allowsFullSwipe:content:onPresentationChanged:) and swipeActionsContainer().

[…]

Use the visibilityPriority(_:) modifier to prioritize important toolbar actions so SwiftUI keeps them visible as space shrinks, moving lower-priority items to the overflow menu first.

[…]

Present an alert or confirmation dialog from an optional data item or error object, and use that data to produce the content and title[…]

What’s new in SwiftUI:

Explore the latest additions to SwiftUI and discover how they can improve your apps. We’ll introduce a new Document protocol with direct disk access and snapshot-based diffing for building high-performance apps; new APIs for reordering content in lists, grids, and sections; and toolbar enhancements including visibility priority and auto-minimizing behavior. We’ll also cover expanded presentation APIs — including swipe actions on any view — plus AsyncImage caching improvements and lazy state initialization for Observable types.

Use SwiftUI with AppKit and UIKit:

Discover how to incrementally adopt SwiftUI in your existing AppKit or UIKit app. We’ll show you how to use the Observation framework to automatically update your views, integrate SwiftUI components into an existing view hierarchy, and bring gesture recognizers into SwiftUI. We’ll also explore how to add complete SwiftUI scenes to your app without changing your overall architecture.

Dive into lazy stacks and scrolling with SwiftUI:

Discover the inner workings of lazy stacks in SwiftUI. We’ll explore how LazyVStack and LazyHStack estimate sizes, lazily load subviews, and prefetch content to deliver smooth scrolling experiences. We’ll also cover advanced performance optimizations, state management best practices, and tips for precise programmatic scrolling. To get the most out of this session, we recommend basic familiarity with SwiftUI layout using stacks.

Compose advanced graphics effects with SwiftUI:

Discover how to craft rich, custom experiences by creatively composing SwiftUI layout and graphics APIs. We’ll show you how to break down complex designs and use a creative pipeline to chain simple building blocks together. Learn how to draw with layer shaders, animate with timelines, and anchor views with alignment guides.

Build powerful drag and drop in SwiftUI:

Follow along as we build a game of Solitaire to explore the latest drag-and-drop capabilities in SwiftUI. We’ll show you how to use the new reordering API to let people arrange content, implement drag containers to move multiple items at once, and customize the drag-and-drop lifecycle to fit your app’s rules.

There are also a bunch of labs.

Natalia Panferova:

Up until now it was a property wrapper conforming to the DynamicProperty protocol, but in Xcode 27 it becomes a Swift macro. In this post we will look at what the change means for @Observable models stored in @State.

Malcolm Hall:

Only took 3 years lol!

Majid Jabrayilov:

SwiftUI also introduces a new prominent tab role. You can use the prominent role for trailing-separated tabs, similar to search.

[…]

Document-based apps get a refreshed look and feel, along with a performance boost. It looks like Xcode has started using these improvements, which might explain why we see so much work around document-based apps this year. And finally, Xcode introduces SwiftUI Specialist and What’s New in SwiftUI skills for agentic coding in Xcode.

Fatbobman:

For me, the biggest change in SwiftUI comes from its comprehensive support for document-based apps. It not only adds a large number of new APIs, but also shifts the mental model toward “observable document objects + asynchronous snapshots + dedicated readers / writers.” This is clearly better suited to complex document apps, and it also aligns more closely with the overall evolution of modern Swift around Observation and Concurrency.

The sessions also mentioned that SwiftUI continues to optimize layout- and container-related implementations, bringing noticeable performance improvements in some scenarios. This is an improvement developers have urgently needed. However, SwiftUI still does not provide the ability to create custom Lazy containers, which remains a clear disappointment.

Natalia Panferova:

iOS 27 introduces new reordering APIs that work with any container. We can mark dynamic content with reorderable() and define the scope of the interaction with reorderContainer(for:). SwiftUI handles the drag preview, insertion placeholder, and drop animation, while our code applies the resulting change to the model.

SwiftUI’s drag container APIs are also now available on iPhone and iPad, after previously being limited to macOS. They let us make items in a collection draggable without making the collection reorderable, and include multiple selected items in the same drag. The APIs also support lazy generation of transferable values and drag-session observation.

robb:

I love the new #SwiftUI Text selection but without a way to make selection span multiple Texts in a group, it doesn’t really address our needs at Linear – here’s hoping we see an update in a later seed 🤞

Natalia Panferova:

The NavigationTransition protocol has been available in SwiftUI since iOS 18, letting us control how views animate when pushed onto a NavigationStack and when presenting sheets and full-screen covers. We specify the transition using the navigationTransition(_:) modifier on the destination or presented view, and SwiftUI uses it instead of the default animation for that context. Before iOS 27, SwiftUI provided two built-in conforming types: AutomaticNavigationTransition, used via the automatic static value, which defers to the system default for the current context, and ZoomNavigationTransition, used via zoom(sourceID:in:), which animates the presented view expanding from a source view marked with matchedTransitionSource(). iOS 27 introduces CrossFadeNavigationTransition, a new built-in transition that cross-fades between views without requiring a source, and adds AnyNavigationTransition, a type eraser that lets us select a transition at runtime.

Kyle Howells:

The last few years watching WWDC has been a mixed experience for me, because I honestly believe Swift and SwiftUI are actively either bad or being made worst.

Yet every year, the problems I have with them are doubled down on, not improved.

Kyle-Ye:

The FB21333309 cache bug I submitted is now confirmed to be fixed on iOS 27.

Instead of introducing a new CacheKey like I suggested, SwiftUI team choose to move the intensity payload out of the FeedbackType enum to a new Payload enum and add a new payload var to SensoryFeedback storage.

dasdom:

A few weeks ago I realised that most iOS jobs require knowledge of SwiftUI. So I started to rebuild my Mastodon client in SwiftUI. Then I got an offer for a new job and accepted it. This means I can get back to working on the ObjC version. Feels good. :)

Previously:

Update (2026-06-23): Natalia Panferova:

iOS 27 adds new AsyncImage initializers that accept a URLRequest instead of a URL. We can now configure request headers, cache policy, and timeout interval while continuing to use the built-in loading and phase handling provided by AsyncImage. A new asyncImageURLSession(_:) modifier also lets us provide the URL session used by asynchronous images in a view hierarchy.

Update (2026-07-10): Luc Vandal:

SwiftUI .reorderable() crashes when the reordered view body contains if #available: “Unexpected identifier type. Expected [Type], got [Type]”

[…]

Even attaching a .popover to an item causes it to crash when reordering.

Update (2026-07-23): Yakov Manshin (video, via Mohammad Azam):

Seven years after its blockbuster 2019 announcement, SwiftUI was supposed to be the mature, production-grade future of cross-platform UI development on all Apple platforms. Instead, SwiftUI feels like a perpetual beta, even in 2026. In this deep dive, I break down why the initial excitement has given way to deep professional frustration for senior engineers. I analyze the systemic issues with performance and layout predictability, the chaotic state of SwiftUI’s ever-changing data flow, and the frustrating lack of backward compatibility that forces developers into a nightmare of shims and workarounds.

Through real-world examples—including Apple’s own SwiftUI tutorial (which is broken) and a head-to-head performance comparison with UIKit (guess who wins)—I demonstrate how SwiftUI trades precise engineering for an illusion of convenience.

Beyond the code, this video explores a broader, more concerning shift in Cupertino: a transition away from the uncompromising craftsmanship of the original era of Cocoa, Aqua, and Auto Layout toward a modern corporate culture of “good enough” products.

  •  

WWDC 2026 Links

General:

Documentation:

Sessions:

Podcasts:

Previously:

  •  

Apple Foundation Models in appleOS 27

Apple:

At the heart of this architecture is our third generation of Apple Foundation Models (AFM), a family of five foundation models custom-built in collaboration with Google. These span from on-device models to server-based models running on Private Cloud Compute.

Apple Foundation Models are built to unlock a wide range of helpful experiences for our users, like an entirely new Siri and intelligent tools that make everyday apps smarter and more useful.

Hartley Charlton:

“The amount of the Google Assistant we use is none,” Federighi said, explaining that Apple uses none of the Gemini models deployed to Google’s customers, none of Google’s client-side code, and no Google Search infrastructure as the knowledge backbone.

Federico Viticci:

The cloud models hosted on Private Cloud Compute are interesting: they’re not “Gemini” models; they’re Apple Foundation Models trained using proprietary data via RL, which were then “refined” with data from Google’s “frontier” models.

[…]

I’ve been covering the AFM family of models for a while now, and AFM Core Advanced is one of the most interesting on-device models I’ve read about in a while, especially in the context of model size for mobile devices and built-in multimodality with support for text, images, and audio. I’m very keen to play around with this model and understand how it holds up in practice. I wonder if the new CLI (!) for AFM will let you test this one.

Awni Hannun:

It’s very cool that Apple shipped a 20B parameter on-device.

You can’t put 20B parameters in RAM at any reasonable precision. To make it work they are using pretty exotic architecture by today’s standards.

A small model predicts from the query (or prompt) which experts to load from Nand into RAM. The key distinction from a typical MoE is that you do this once per query and then generate all the tokens with the same experts (instead of switching the experts for every token).

Greg Pierce:

Looks like there’s still a 4K context size on local FoundationModels. Pretty limiting.

Kyle Howells:

Really disappointed SwiftUI’s result builder syntax has infected FoundationModels API too.

How did a million modifier methods become the default way to build APIs?

It’s horrible for discoverability, code completion, documentation.

Steve Troughton-Smith:

FoundationModels is one of the highlights of this WWDC; I think it’s now finally what we hoped we were getting two years ago, and thought we were getting last year (just the models themselves were barely up for it then). I finally feel like I can build features with it, though I really don’t like the Sword of Damocles Apple is holding above Private Cloud Compute and how it can permanently lock you out of using the models forever across all your apps if you hit a download threshold. Poison pill

John Gruber (Mastodon):

These strict limits don’t seem to be getting as much attention as they should. It’s nice that for small developers who meet the above criteria, access to PCC has no cost. But there’s no way (yet?) to buy your way out of these limits.

[…]

The “fewer than 2 million first-time app downloads from any of their apps” restriction is particularly notable. It’s not 2 million installations for apps that are using PCC, but 2 million downloads for any app the developer has ever released.

Chad Podoski:

Is there a real time count somewhere of total lifetime downloads for a developer account, so one can plan if they at risk of the switch tripping? Reminds me of the small business qualifications. I had to try to figure out if an employers developer account was going to exceed the revenue threshold for the year. I was left trying to determine it from sales reports, not to mention sales date versus pay out date confusion. I think I botched the calculation in the end.

Anthropic (Hacker News):

Claude for Foundation Models is a Swift package that makes Claude available as a server-side language model in Apple’s Foundation Models framework. The package conforms Claude to the framework’s LanguageModel protocol, so you drive it with the same LanguageModelSession API you use for Apple’s on-device model: respond(to:), streaming, guided generation, and tool calling all work the same way.

Requests go directly from your app to the Claude API; Apple is not in the request path and does not see prompts or responses. Usage is billed to your Anthropic account at standard API pricing.

Previously:

Update (2026-06-17): Simon B. Støvring:

Apple is literally stopping me from building a brand new app using Private Cloud Compute because I made a successful app a few years ago.

The new app might be a success, or it might be a complete flop. Nobody knows yet.

I would understand it if Apple were to limit developers once an app reaches a certain number of downloads or active users, but that’s not what’s happening here.

Instead, they’re blocking developers before they’ve even had a chance to build and ship the app.

  •  

Rewriting Apple’s TrueType Hinting Interpreter in Swift

Scott Perry:

My team rewrote Apple’s TrueType hinting interpreter in Swift, ask me anything.

[…]

I feel like naming just one would be a disservices to all of the features that made this effort possible (C interop, generics, noncopyable/nonescapable types) but at the end of the day I think the star of the show was the optimizer; despite being faster than the code it replaced, the new code is super readable and that was only possible because the optimizer was able to completely eliminate all of our abstractions.

The new version is faster, but the main motivation was security concerns.

Dmitrii Kalianov:

Is hinting useful/being used in the days of hi-dpi displays? I was under impression that Apple switched to grayscale anti-aliasing and ditched hinting.

Scott Perry:

For the most part hinting isn’t really necessary anymore, but thanks to being Turing-complete it has been Hyrum’s law-ed by at least one CJK font that uses hinting to lay out strokes in its characters.

Alex Rosenberg:

There were three major TrueType implementations at Apple IIRC:

  • The original 68K one
  • A rewrite for Copland that lived with ATS/ATSUI after Copland was cancelled
  • iPhone shipped one derived from heavily-modified FreeType that was current until today

Scott Perry:

One of the axioms for this project was that I wanted my team to write the most boring code possible—nearly identical structurally to the code it was replacing, because to do otherwise would introduce binary compatibility risk. The other axiom was 100% test coverage for all new code as it landed, with the same units testing both interpreters.

Rosyna Keller:

Is the font parsing code itself still C++?

Scott Perry:

There is also a “Safe Font Parser” for WebKit in Lockdown Mode, but it supports a subset of all the myriad features provided by font formats.

Previously:

Update (2026-06-16): Scott Perry (Hacker News):

Font parsers process data from untrusted sources, making the TrueType hinting interpreter a security-critical attack surface. To make the format more resilient on Apple platforms, we rewrote its hinting interpreter from C to memory-safe Swift for the Fall 2025 releases. In addition to memory safety, we also improved performance: on average, our Swift interpreter runs 13% faster than the C interpreter it replaced.

[…]

Binary compatibility was crucial for this project to succeed: existing programs had to continue to function the same as they did before, effectively unaware that a new implementation was in place. This means not just interface compatibility but pixel-identical glyph rendering as well, relative to the C implementation.

[…]

To ensure correctness, we developed two test suites. The first was a unit test suite that can target both implementations, providing exhaustive (99.7%) code coverage for both. This suite is included with the open source release of the Swift interpreter.

Then, to represent real-world workloads, we used a fuzzer to minimize a corpus of 10 million PDF files down to 4,200 without any loss of code coverage.

[…]

Following WebKit’s Safer Swift Guidelines, the example below demonstrates how to wrap a bridged structure from C in a projection type that uses Ref for lifetime safety, brokers bounds-safe access to the underlying data, and returns idiomatic Swift types to its callers.

The interpreter source is on GitHub.

Marcin Krzyzanowski:

@_lifetime(copy code, copy twilightZone, copy glyphZone)

See also: Phillip Tennen’s Writing a TrueType font renderer (Hacker News).

Previously:

  •  

Rewriting Notion in SwiftUI

Hartley Charlton:

Apple this week confirmed that Notion is migrating its user interface to SwiftUI, citing the app’s desire for greater performance and UI consistency than its existing web-based stack can deliver.

[…]

The callout was clearly deliberate; Notion is one of the most widely used productivity apps on the Mac, and has long been criticized for the sluggishness that comes with its Electron-based architecture.

Previously:

  •  
❌