We're building a UGC AR app and are leveraging App Clips to distribute AR experiences without app download.
Since earlier this week, many of our users are reporting sharing experiences as App Clip doesn't work anymore. They are getting the message "AppClip unavailable" on a little card. We attached a QR code to try it yourself and a link to a different experience. We tried with multiple experiences and on multiple devices already.
https://scenery.app/experience/1C925FDE-E49A-489B-BA14-58A4E532E645
Interestingly, we can't pinpoint the issue to an exact device or OS.
We tested on many devices and on most, the AppClip is being displayed as unavailable, stating "App Clip unavailable", whereas it works on a few. It all worked fine last week (before September 12th).
iPhone 13 Pro Max, iOS26: works
iPhone SE, iOS 17: works
iPhone 16 Pro, iOS 26: doesn't work
iPhone 12 Pro Max, iOS 26: doesn't work
iPhone 12 mini, iOS 18: does not work
iPad 9th gen, iOS 26: doesn't work
Please help. Our users are very dissatisfied as they expect this to work and it's a crucial feature.
We already filed a radar via Feedback assistant:
FB20303890
Explore the various UI frameworks available for building app interfaces. Discuss the use cases for different frameworks, share best practices, and get help with specific framework-related questions.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
Hello, community and Apple engineers. I need your help.
Our app has the following issue: NavigationStack pushes a view twice if the NavigationStack is inside TabView and NavigationStack uses a navigation path of custom Hashable elements.
Our app works with issues in Xcode 18 Beta 13 + iOS 18.0. The same issue happened on previous beta versions of Xcode 18.
The issue isn’t represented in iOS 17.x and everything worked well before iOS 18.0 beta releases.
I was able to represent the same issue in a clear project with two simple views. I will paste the code below.
Several notes:
We use a centralised routing system in our app where all possible routes for navigation path are implemented in a View extension called withAppRouter().
We have a enum RouterDestination that contains all possible routes and is resolved in withAppRouter() extension.
We use Router class that contains @Published var path: [RouterDestination] = [] and this @Published property is bound to NavigationStack. In the real app, we need to have an access to this path property for programmatic navigation purposes.
Our app uses @ObservableObject / @StateObject approach.
import SwiftUI
struct ContentView: View {
@StateObject private var router = Router()
var body: some View {
TabView {
NavigationStack(path: $router.path) {
NavigationLink(value: RouterDestination.next, label: {
Label("Next", systemImage: "plus.circle.fill")
})
.withAppRouter()
}
}
}
}
enum RouterDestination: Hashable {
case next
}
struct SecondView: View {
var body: some View {
Text("Screen 2")
}
}
class Router: ObservableObject {
@Published var path: [RouterDestination] = []
}
extension View {
func withAppRouter() -> some View {
navigationDestination(for: RouterDestination.self) { destination in
switch destination {
case .next:
return SecondView()
}
}
}
}
Below you can see the GIF with the issue:
What I tried to do:
Use iOS 17+ @Observable approach. It didn’t help.
Using @State var path: [RouterDestination] = [] directly inside View seems to help. But it is not what we want as we need this property to be @Published and located inside Router class where we can get an access to it, and use for programmatic navigation if needed.
I ask Apple engineers to help with that, please, and if it is a bug of iOS 18 beta, then please fix it in the next versions of iOS 18.0
We're seeing a sharp uptick in BaseBoard/FrontBoardServices crashes since we migrated from UIApplicationDelegate to UIWindowSceneDelegate. Having exhausted everything on my end short of reverse engineering BaseBoard or making changes without being able to know if they work, I need help. I think all I need to get unstuck is an answer to these questions, if possible:
What does -[BSSettings initWithSettings:] enumerate over? If I know what's being enumerated, I'll know what to look for in our app.
What triggers FrontBoardServices to do this update? If I can reproduce the crash--or at least better understand when it may happen--I will be better able to fix it
Here's two similar stack traces:
App_(iOS)-crashreport-07-30-2025_1040-0600-redacted.crash
App_(iOS)-crashreport-07-30-2025_1045-0600-redacted.crash
Since these are private trameworks, there is no documentation or information on their behavior that I can find.
There are other forum posts regarding this crash, on here and on other sites. However, I did not find any that shed any insight on the cause or conditions of the crash. Additionally, this is on iPhone, not macOS, and not iPad. This post is different, because I'm asking specific questions that can be answered by someone with familiarity on how these internal frameworks work. I'm not asking for help debugging my application, though I'd gladly take any suggestions/tips!
Here's the long version, in case anyone finds it useful:
In our application, we have seen a sharp rise in crashes in BaseBoard and FrontBoardServices, which are internal iOS frameworks, since we migrated our app to use UIWindowSceneDelegate. We were using exclusively UIApplicationDelegate before. The stack traces haven't proven very useful yet, because we haven't been able to reproduce the crashes ourselves.
Upon searching online, we have learned that Baseboard/Frontsoardservices are probably copying scene settings upon something in the scene changing. Based on our crash reports, we know that most of our users are on an iPhone, not an iPad or macOS, so we can rule out split screen or window resizing. Our app is locked to portrait as well, so we can also rule out orientation changes. And considering the stack trace is in the middle of an objc_retain_x2 call, which is itself inside of a collection enumeration, we are assuming that whatever is being enumerated probably was changed or deallocated during enumeration. Sometimes it's objc_retain_x2, and sometimes it's a release call. And sometimes it's a completely different stack trace, but still within BaseBoard/FrontBoardServices. I suspect these all share the same cause.
Because it's thread 0 that crashed, we know that BaseBoard/FrontBoardServices were running on the main thread, which means that for this crash to occur, something might be changing on a background thread. This is what leads me to suspect a race condition.
There are many places in our app where we accidentally update the UI from a background thread. We've fixed many of them, but I'm sure there are more. Our app is large. Because of this, I think background UI are the most likely cause. However, since I can't reproduce the crash, and because none of our stack traces clearly show UI updates happening on another thread at the same time, I am not certain.
And here's the stack trace inline, in case the attachments expire or search engines can't read them:
Thread 0 name:
Thread 0 Crashed:
objc_retain_x2 (libobjc.A.dylib)
BSIntegerMapEnumerateWithBlock (BaseBoard)
-[BSSettings initWithSettings:] (BaseBoard)
-[BSKeyedSettings initWithSettings:] (BaseBoard)
-[FBSSettings _settings:] (FrontBoardServices)
-[FBSSettings _settings] (FrontBoardServices)
-[FBSSettingsDiff applyToMutableSettings:] (FrontBoardServices)
-[FBSSettingsDiff settingsByApplyingToMutableCopyOfSettings:] (FrontBoardServices)
-[FBSSceneSettingsDiff settingsByApplyingToMutableCopyOfSettings:] (FrontBoardServices)
-[FBSScene updater:didUpdateSettings:withDiff:transitionContext:completion:] (FrontBoardServices)
__94-[FBSWorkspaceScenesClient _queue_updateScene:withSettings:diff:transitionContext:completion:]_block_invoke_2 (FrontBoardServices)
-[FBSWorkspace _calloutQueue_executeCalloutFromSource:withBlock:] (FrontBoardServices)
__94-[FBSWorkspaceScenesClient _queue_updateScene:withSettings:diff:transitionContext:completion:]_block_invoke.cold.1 (FrontBoardServices)
__94-[FBSWorkspaceScenesClient _queue_updateScene:withSettings:diff:transitionContext:completion:]_block_invoke (FrontBoardServices)
_dispatch_client_callout (libdispatch.dylib)
_dispatch_block_invoke_direct (libdispatch.dylib)
__FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ (FrontBoardServices)
-[FBSMainRunLoopSerialQueue _targetQueue_performNextIfPossible] (FrontBoardServices)
-[FBSMainRunLoopSerialQueue _performNextFromRunLoopSource] (FrontBoardServices)
__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ (CoreFoundation)
__CFRunLoopDoSource0 (CoreFoundation)
__CFRunLoopDoSources0 (CoreFoundation)
__CFRunLoopRun (CoreFoundation)
CFRunLoopRunSpecific (CoreFoundation)
GSEventRunModal (GraphicsServices)
-[UIApplication _run] (UIKitCore)
UIApplicationMain (UIKitCore)
(null) (UIKitCore)
main (AppDelegate.swift:0)
0x1ab8cbf08 + 0
When building with iOS 26 SDK beta 5 (23A5308f), onTapGesture is no longer being triggered on Map views. This appears to be a regression in beta 5 specifically, as this issue was not present in beta 4.
How to reproduce
Code
The following code demonstrates the issue, as seen in the videos below.
import MapKit
import SwiftUI
struct ContentView: View {
@State private var location = CGPoint.zero
var body: some View {
Map()
.onTapGesture { location in
self.location = location
}
.safeAreaInset(edge: .bottom) {
VStack(alignment: .center) {
Text("iOS \(UIDevice.current.systemVersion)")
.font(.largeTitle)
Text("Tapped Location")
Text("\(location.x), \(location.y)")
}
.frame(maxWidth: .infinity, alignment: .center)
.background(.background)
}
}
}
Demo
The gifs below show the behavior in iOS 18.5 (in which the tap gestures are recognized and tapped coordinate is displayed in the safe area inset) and iOS 26 beta 5 (in which the tap gestures have no effect):
iOS 18
iOS 26
Next steps?
Is there a recommended workaround for this issue?
Summary
As presented in the SwiftUI WWDC video, the new tabViewBottomAccessory should allow for unique contents for .inline. This is what was presented as being used for the Apple Music miniplayer. However, the functionality seems to be either missing or unintuitive. As seen in the photos attached, not only does .inline functionality not seem to do anything, but the inline accessory also has misaligned elements that cannot be fixed by conditionally modifying the contents.
Build Target
iOS 26.0
Details
This problem recurs on physical devices, simulators, and Xcode previews.
Here is a view I've constructed for use as a tabViewBottomAccessory:
struct FitnessToolbarAccessory: View {
@Environment(\.tabViewBottomAccessoryPlacement) var placement
var body: some View {
if (placement == .inline) {
Text("hello")
} else {
HStack {
HStack {
Image(systemName: "dumbbell.fill")
VStack(alignment: .leading) {
Text("Active Workout")
Text("Push Day - Chest")
.font(.system(size: 13))
}
Spacer()
Image(systemName: "pause.fill")
}
.padding()
}
}
}
}
Here is the result, working as expected in expanded mode:
And here is the result in inline mode after minimizing the tabViewBottomAccessory:
The content of this inline accessory is clearly incorrect, as it was specified to contain a Text view containing "hello". Additionally, the contents seem to have some incorrect alignment. This occurs regardless of the contents of the accessory, even plain text.
Basically when showing a view using the .fullScreenCover modifier, it has no background anymore, any other UI elements are still shown but the view under it is also still shown.
Right now, the traffic light buttons overlapped on my iPad app top corner on windows mode (full screen is fine).
How do I properly design my app to avoid the traffic light buttons? Detect that it is iPadOS 26?
Topic:
UI Frameworks
SubTopic:
SwiftUI
[Also submitted as FB21536505]
When presenting a NavigationStack inside a .sheet, applying .tint(Color) does not affect the system back button on pushed destinations. The sheet’s close button adopts the tint, but the back chevron remains the default system color.
REPRO
Create a new iOS project and replace ContentView.swift with the code below.
—or—
Present a .sheet containing a NavigationStack.
Apply .tint(.red) to the NavigationStack or sheet content.
Push a destination using NavigationLink.
EXPECTED
The back button chevron adopts the provided tint color, consistent with other toolbar buttons and UIKit navigation behavior.
ACTUAL
The back button chevron remains the default system color.
NOTES
Reproduces consistently on:
iOS 26.2 (23C54)
iOS 26.3 (23D5089e)
SCREEN RECORDING
SAMPLE CODE
import SwiftUI
struct ContentView: View {
@State private var isSheetPresented = false
var body: some View {
Button("Open Settings Sheet") {
isSheetPresented = true
}
.sheet(isPresented: $isSheetPresented) {
NavigationStack {
List {
NavigationLink("Push Detail") {
DetailView()
}
}
.navigationTitle("Settings")
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .automatic) {
Button("Close", systemImage: "xmark") {
isSheetPresented = false
}
}
}
}
.tint(.red)
}
}
}
private struct DetailView: View {
var body: some View {
List {
Text("Detail View")
}
.navigationTitle("Detail")
.navigationBarTitleDisplayMode(.inline)
}
}
When I dismiss a view presented with .navigationTransition(.zoom), the source view gets a weird background (black or white depending on the appearance) for a couple of seconds, and then it disappears.
Here’s a simple code example.
import SwiftUI
struct NavigationTransition: View {
@Namespace private var namespace
@State private var isSecondViewPresented = false
var body: some View {
NavigationStack {
ZStack {
DetailView(namespace: namespace)
.onTapGesture {
isSecondViewPresented = true
}
}
.fullScreenCover(isPresented: $isSecondViewPresented) {
SecondView()
.navigationTransition(.zoom(sourceID: "world", in: namespace))
}
}
}
}
struct DetailView: View {
var namespace: Namespace.ID
var body: some View {
ZStack {
Color.blue
Text("Hello World!")
.foregroundStyle(.white)
.matchedTransitionSource(id: "world", in: namespace)
}
.ignoresSafeArea()
}
}
struct SecondView: View {
var body: some View {
ZStack {
Color.green
Image(systemName: "globe")
.foregroundStyle(Color.red)
}
.ignoresSafeArea()
}
}
#Preview {
NavigationTransition()
}
Using an App Clip link encoded into a QR Code shows an error when scanning the encoded QR Code on an iPhone or iPad.
After being scanned, the App Clip's banner is visible, but a message says: "App Clip Unavailable".
Accessing the same App Clip URL via Safari works as expected.
I've filed a feedback with more details and screenshots of the issue here: FB17891015
Thanks!
Hello there!
I wanted to give a native scrolling mechanism for the Swift Charts Graph a try and experiment a bit if the scenario that we try to achieve might be possible, but it seems that the Swift Charts scrolling performance is very poor.
The graph was created as follows:
X-axis is created based on a date range,
Y-axis is created based on an integer values between moreless 0-320 value.
the graph is scrollable horizontally only (x-axis),
The time range (x-axis) for the scrolling content was set to one year from now date (so the user can scroll one year into the past as a minimum visible date (.chartXScale).
The X-axis shows 3 hours of data per screen width (.chartXVisibleDomain).
The data points for the graph are generated once when screen is about to appear so that the Charts engine can use it (no lazy loading implemented yet).
The line data points (LineMark views) consist of 2880 data points distributed every 5 minutes which simulates - two days of continuous data stream that we want to present. The rest of the graph displays no data at all.
The performance result:
The graph on the initial loading phase is frozen for about 10-15 seconds until the data appears on the graph.
Scrolling is very laggy - the CPU usage is 100% and is unacceptable for the end users.
If we show no data at all on the graph (so no LineMark views are created at all) - the result is similar - the empty graph scrolling is also very laggy.
Below I am sharing a test code:
@main
struct ChartsTestApp: App {
var body: some Scene {
WindowGroup {
ContentView()
Spacer()
}
}
}
struct LineDataPoint: Identifiable, Equatable {
var id: Int
let date: Date
let value: Int
}
actor TestData {
func generate(startDate: Date) async -> [LineDataPoint] {
var values: [LineDataPoint] = []
for i in 0..<(1440 * 2) {
values.append(
LineDataPoint(
id: i,
date: startDate.addingTimeInterval(
TimeInterval(60 * 5 * i) // Every 5 minutes
),
value: Int.random(in: 1...100)
)
)
}
return values
}
}
struct ContentView: View {
var startDate: Date {
return endDate.addingTimeInterval(-3600*24*30*12) // one year into the past from now
}
let endDate = Date()
@State var dataPoints: [LineDataPoint] = []
var body: some View {
Chart {
ForEach(dataPoints) { item in
LineMark(
x: .value("Date", item.date),
y: .value("Value", item.value),
series: .value("Series", "Test")
)
}
}
.frame(height: 200)
.chartScrollableAxes(.horizontal)
.chartYAxis(.hidden)
.chartXScale(domain: startDate...endDate) // one year possibility to scroll back
.chartXVisibleDomain(length: 3600 * 3) // 3 hours visible on screen
.onAppear {
Task {
dataPoints = await TestData().generate(startDate: startDate)
}
}
}
}
I would be grateful for any insights or suggestions on how to improve it or if it's planned to be improved in the future.
Currently, I use UIKit CollectionView where we split the graph into smaller chunks of the graph and we present the SwiftUI Chart content in the cells, so we use the scrolling offered there. I wonder if it's possible to use native SwiftUI for such a scenario so that later on we could also implement some kind of lazy loading of the data as the user scrolls into the past.
With the introduction of the new matchedTransitionSource from iOS 18, we can apply a zoom transition in the navigation view using .navigationTransition(.zoom) This works well for zoom animations.
However, when I try to apply a matched geometry effect to views that are similar in the source and destination views, the zoom transition works, but those views don't transition seamlessly as they do with a matched geometry effect.
Is it possible to still use matched geometry for subviews of the source and destination views along with the new navigationTransition?
Here’s a little demo that reproduces this behaviour:
struct ContentView: View {
let colors: [[Color]] = [
[.red, .blue, .green],
[.yellow, .purple, .brown],
[.cyan, .gray]
]
@Namespace() var namespace
var body: some View {
NavigationStack {
Grid(horizontalSpacing: 50, verticalSpacing: 50) {
ForEach(colors, id: \.hashValue) { rowColors in
GridRow {
ForEach(rowColors, id: \.self) { color in
NavigationLink {
DetailView(color: color, namespace: namespace)
.navigationTransition(
.zoom(
sourceID: color,
in: namespace
)
)
.edgesIgnoringSafeArea(.all)
} label: {
ZStack {
RoundedRectangle(cornerRadius: 5)
.foregroundStyle(color)
.frame(width: 48, height: 48)
Image(systemName: "star.fill")
.foregroundStyle(Material.bar)
.matchedGeometryEffect(id: color,
in: namespace,
properties: .frame, isSource: false)
}
}
.matchedTransitionSource(id: color, in: namespace)
}
}
}
}
}
}
}
struct DetailView: View {
var color: Color
let namespace: Namespace.ID
var body: some View {
ZStack {
color
Image(systemName: "star.fill")
.resizable()
.foregroundStyle(Material.bar)
.matchedGeometryEffect(id: color,
in: namespace,
properties: .frame, isSource: false)
.frame(width: 100, height: 100)
}
.navigationBarHidden(false)
}
}
#Preview {
ContentView()
}
We have encountered a problem on iOS 26. When switching to dark mode, the color of all subviews (font color, background color, etc.) of the Sidebar (Primary View) of UISplitViewController will not change. For example, if it is set to the color of UIColor.label, it will always be black and will not be white in dark mode.
On Xcode, just create a UISplitViewController in Storyboard without changing any settings, and run it directly to see the following:
The title of the Navigation Bar defaults to the label color, and it is still black after switching to dark mode.
There is no such problem in the Secondary View or other places.
This problem has occurred since iOS 26 beta 3, and iOS 26 beta 4 is now the same. But beta 1 and beta 2 have no problem.
I'm not sure if this is a bug, or if there is something that needs to be changed to adapt to iOS 26?
While testing my application on iOS beta 26, I am experiencing issues with the native UISegmentedControl component from UIKit. After implementing the control, I noticed that I am unable to switch to the second segment option—the selection remains fixed on the first segment regardless of user interaction. I have already reviewed the initial configuration of the control, the addition of the segments, and the implementation of the target-action, but the issue persists. I would like to understand what could be causing this behavior and if there are any specific adjustments or workarounds for iOS 26.
I created a minimal application containing only a UISegmentedControl to clearly demonstrate the issue.
It looks like we're encountering a similar hitTest issue to what we had with iOS Xcode 16 + iOS 18.
When running Xcode 26 + iOS 26, rootViewController?.view.subviews is returning an empty array, even though the views are clearly present in the hierarchy.
Last year, we "fixed" this issue using the code attached, but it doesn't seem to work anymore with iOS 26.
Any suggestions would be greatly appreciated!
private class PassthroughWindow: UIWindow {
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
guard let hitView = super.hitTest(point, with: event),
let rootView = rootViewController?.view
else {
return nil
}
if #available(iOS 18, *) {
for subview in rootView.subviews.reversed() {
let convertedPoint = subview.convert(point, from: rootView)
if subview.hitTest(convertedPoint, with: event) != nil {
return hitView
}
}
return nil
} else {
return hitView == rootView ? nil : hitView
}
}
}
Topic:
UI Frameworks
SubTopic:
UIKit
I'm running into a persistent problem with the iOS 18.5 simulator in Xcode 26 beta 2. I have built a very simple test app with a storyboard that includes only a toolbar added to the ViewController scene in the storyboard. The test app runs fine in iOS 26 simulators.When I try to run it in the iOS 18.5 simulator for iPhone Pro or iPad (16), it fails while unarchiving the storyboard (as far as I can tell) with this error message in the Xcode console:
*** Terminating app due to uncaught exception 'NSInvalidUnarchiveOperationException', reason: 'Could not instantiate class named TtGC5UIKit17UICoreHostingViewVCS_21ToolbarVisualProvider8RootView because no class named TtGC5UIKit17UICoreHostingViewVCS_21ToolbarVisualProvider8RootView was found; the class needs to be defined in source code or linked in from a library (ensure the class is part of the correct target)'
terminating due to uncaught exception of type NSException
CoreSimulator 1043 - Device: iPad (A16) (3E70E25F-8434-4541-960D-1B58EB4037F3) - Runtime: iOS 18.5 (22F77) - DeviceType: iPad (A16)
I'd love a simple workaround for this.
Is there any way to prevent the keyboard from bouncing when changing the focus state in onSubmit? Or is it not recommended to change focus in onSubmit?
The following view is setup so that pressing return on the keyboard should cause focus to move between the TextFields.
struct TextFieldFocusState: View {
enum Field {
case field1
case field2
}
@FocusState var focusedField: Field?
var body: some View {
Form {
TextField("Field 1", text: .constant(""))
.focused($focusedField, equals: .field1)
.onSubmit { focusedField = .field2 }
TextField("Field 2", text: .constant(""))
.focused($focusedField, equals: .field2)
.onSubmit { focusedField = .field1 }
}
}
}
I would expect that when pressing return, the keyboard would say on screen.
What actually happens is the keyboard appears to bounce when the return key is pressed (first half of gif). I assume this is because onSubmit starts dismissing the keyboard then setting the focus state causes the keyboard to be presented again.
The issue doesn't occur when tapping directly on the text fields to change focus (second half of gif).
Hello Apple Developer Community: I have a problem with the fullscreencover. I can see the Things, that shouldn’t be visible behind it.
I’m currently developing with iOS 26 and only there it happens.
I hope you can help me :)
Have a nice day
The sample code provided in "Building a document-based app with SwiftUI" (https://developer.apple.com/documentation/swiftui/building-a-document-based-app-with-swiftui) does not work as expected.
The DocumentGroup/StoryView toolbar does not appear for documents opened in the App.
By removing the DocumentGroupLaunchScene block from the App the toolbar does appear and works as expected - but of course the App's DocumentGroupLaunchScene customizations are lost.
I've tested this on 18.0 devices, as well as production 18.0 and 18.1 beta 6 simulators.
If I modify the StoryView by wrapping the content in a NavigationStack I can make some progress - but the results are unstable and hard to pin down - with this change the first time a document is opened in the WritingApp the toolbar appears as expected. When opening a document subsequently the toolbar is corrupted.
Please is this a bug or is there a good example of incorporate both DocumentGroupLaunchScene customizations at the App level and retina the toolbar in documents presented via DocumentGroup?
Topic:
UI Frameworks
SubTopic:
SwiftUI
I'm trying to do something so seemingly basic, yet I can't get it to work and I'm flummoxed.
In a basic, vanilla SwiftUI app for tvOS, embed a single Text element with a very long string (hundreds of lines) in it:
struct ContentView: View {
var body: some View {
ScrollView(.vertical) {
Text(veryLargeString)
.focusable()
}
}
}
Then fire up the app on tvOS, and it will not scroll. No matter what I do. Pressing arrow keys, swiping fast with my thumb, and nothing. It will not move. Ironically, in the Xcode SwiftUI Preview window—it does scroll, so that's always a fun tease.
What I do know is that the focus engine is throwing a few errors, so it's leading me to believe the issue is with how I have the focusable element attached. I'm using a combination of -UIFocusLoggingEnabled YES as well as listening for UIFocusSystem.movementDidFailNotification.
Unfortunately since this is SwiftUI, the notification failure and debugging logs aren't really all that actionable. Help appreciated!