In iOS 18, TabView with .tabViewStyle(.sidebarAdaptable) introduced a powerful adaptive pattern — tabs in compact, sidebar in regular. However, the current Tab API only supports a title and an image (icon). There is no way to provide a trailing accessory view (e.g., a secondary icon or indicator) for sidebar rows.
This is a meaningful gap in the API, because trailing accessories are a well-established pattern throughout UIKit and SwiftUI.
Precedent in Apple's own design language
Apple already supports trailing accessories in many analogous contexts:
UITableViewCell / UICollectionViewListCell — support accessories (disclosure indicators, checkmarks, custom views) via UICellAccessory.
UIListContentConfiguration — allows leading and trailing content in list rows.
SwiftUI List rows — support Label, HStack with trailing elements, .badge(), and swipeActions.
NavigationLink — automatically renders a disclosure chevron as a trailing accessory.
UITabSidebarItem (UIKit, iOS 18) — supports configurationUpdateHandler and cell accessories at the UIKit level.
The sidebar of a .sidebarAdaptable TabView is visually identical to a List — yet its rows lack the accessory support that List rows have had for years.
Real-world example: Photos app
Apple's own Photos app (iPadOS 18+) demonstrates this exact need. In its sidebar, the "Recently Deleted" row displays a trailing lock icon to indicate that authentication is required to view the album. This is a meaningful UX element — it communicates state at a glance, without requiring the user to tap into the item.
Third-party developers building with TabView(.sidebarAdaptable) have no public API to replicate this pattern. The Tab view builder's label closure is decomposed into a discrete title and image; any additional views (including Spacer() and trailing Image views within an HStack) are silently discarded by the system.
What we've tried
Custom label closure with HStack — trailing views are ignored. The system extracts only the first Image and Text.
.badge() modifier — only supports Int or Text, not custom views such as icons.
Label with complex content — the system normalizes it to icon + title.
The only viable path today is to bridge to UIKit's UITabBarController and customize UITabSidebarItem directly, which defeats the purpose of using SwiftUI's declarative TabView API.
Proposed API
A trailing accessory modifier on Tab, consistent with existing SwiftUI patterns:
Tab("Recently Deleted", systemImage: "trash", value: "deleted") {
RecentlyDeletedView()
}
.tabSidebarAccessory {
Image(systemName: "lock.fill")
.foregroundStyle(.secondary)
}
// Option B: Text accessory (e.g., counts, status labels)
Tab("Inbox", systemImage: "tray", value: "inbox") {
InboxView()
}
.tabSidebarAccessory {
Text("12")
.font(.subheadline)
.foregroundStyle(.secondary)
}
// Option C: Combined text + image accessory
Tab("Shared Albums", systemImage: "rectangle.stack", value: "shared") {
SharedAlbumsView()
}
.tabSidebarAccessory {
HStack(spacing: 4) {
Text("3 new")
.font(.caption)
.foregroundStyle(.secondary)
Image(systemName: "person.2.fill")
.foregroundStyle(.blue)
}
}
Environment
Platform: iPadOS / macOS Catalyst
iOS version: 18.0+
Xcode: 16.0+
Component: SwiftUI TabView with .tabViewStyle(.sidebarAdaptable)
Summary
The Tab API should support trailing accessory content for sidebar rows, bringing it in line with the accessory support already available in UITableViewCell, UICollectionViewListCell, UIListContentConfiguration, and SwiftUI List. Apple's own Photos app demonstrates the need for this capability, yet no public API exists for third-party developers to achieve it.
Mac Catalyst
RSS for tagStart building a native Mac app from your current iPad app using Mac Catalyst.
Posts under Mac Catalyst tag
65 Posts
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I am building an app for iOS and MacCatalyst that indexes files by storing their local paths. Because the app relies on the file remaining at its original location, I only want to accept items that can be opened in place.
I am struggling to determine if an item is "Open In Place" compatible early in the drag-and-drop lifecycle. Specifically:
In dropInteraction(_:canHandle:) and dropInteraction(_:sessionDidUpdate:), calling itemProvider.registeredTypeIdentifiers(fileOptions: [.openInPlace]) returns an empty array.
Only once the drop is actually committed in dropInteraction(_:performDrop:) does that same call return the expected type identifiers.
This creates a poor user experience. I want to validate the "In Place" capability at the very start of the session so the drop target only activates for valid files. If an item is ephemeral (like a dragged photo from the Photos app or a temporary export), the drop zone should not react at all.
How can I reliably detect if an NSItemProvider supports .openInPlace before the performDrop delegate method is called?
Topic:
App & System Services
SubTopic:
General
Tags:
Mac Catalyst
UIKit
Files and Storage
Foundation
Updated version of this post
My HomePod mini is now on version 16.4, so the the temperature and humidity sensors are enabled. The data properly shows up in the Home app on my various devices.
In my HomeKit iPad app running on Mac Catalyst, however, the data does not show up. I would expect the HomePod mini to show up in HMHome.accessories with a service of type HMServiceTypeTempatureSensor. I see all of my other HomeKit accessories, just not the HomePod mini.
I have tried with the latest Xcode (14.3) and highest available iOS Target and Minimum Deployment (16.4), macOS version 13.3. I have not, as of this writing, upgraded my HomeKit architecture, however.
Note that I haven't tried the app on an actual iPad (and the iOS simulator doesn't expose my HomeKit environment.)
When I've tried to use UIDevice on my Mac running my Catalyst application, testing code
UIDevice *d=UIDevice.currentDevice;
for (NSString *k in @[@"name", @"systemName", @"systemVersion", @"model", @"localizedModel"])
NSLog(@"%@ -> %@", k, [d valueForKey:k]);
to my great surprise I am getting
name -> iPad
systemName -> iPadOS
systemVersion -> 26.3
model -> iPad
localizedModel -> iPad
What the. How do I determine the real values? Thanks!
Hi DTS / Apple engineers,
We’re attempting to extending our screen time app target to Mac Catalyst. On iOS, FamilyControls works as expected (AuthorizationCenter + FamilyActivityPicker, then ManagedSettings shields + DeviceActivity monitoring/reporting).
On Mac Catalyst:
The project builds with FamilyControls/DeviceActivity/ManagedSettings capabilities enabled.
But attempting to request FamilyControls authorization (or present FamilyActivityPicker) fails at runtime. We see errors similar to:
Failed to get service proxy: The connection to service named com.apple.FamilyControlsAgent was invalidated: failed at lookup with error 159 - Sandbox restriction.
And our app stays authorizationStatus == .notDetermined, with the request failing.
We saw an Apple engineer suggestion to “disable App Sandbox”, but Mac Catalyst apps appear to always be sandboxed, so we can’t disable it.
Questions:
Is FamilyControls authorization supported on Mac Catalyst today? If so, what entitlement/capability is required specifically for Catalyst/macOS?
If FamilyControls auth cannot succeed on Catalyst, does that mean ManagedSettings shields and DeviceActivity monitoring/reporting are effectively unusable on Catalyst (since they depend on that authorization)?
Is there an Apple‑recommended approach for a Catalyst “portal” app that mirrors an iOS child device’s restrictions, or is local enforcement on Catalyst intentionally unsupported?
Any guidance (and any official docs that clarify current platform support) would be hugely appreciated.
Topic:
App & System Services
SubTopic:
General
Tags:
Mac Catalyst
Family Controls
Device Activity
Managed Settings
I've filed this as FB21446798 but figured I'd post here too.
In the first build of macOS 26.3, playback via ApplicationMusicPlayer is completely broken. When starting playback of anything at all, the console shows the following error:
applicationController: xpc service connection interrupted
Failed to obtain remoteObject: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service created from an endpoint was invalidated from this process." UserInfo={NSDebugDescription=The connection to service created from an endpoint was invalidated from this process.}
Failed to prepareToPlay with error: Error Domain=MPMusicPlayerControllerErrorDomain Code=10 "(null)" UserInfo={NSUnderlyingError=0xc92910ff0 {Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service created from an endpoint was invalidated from this process." UserInfo={NSDebugDescription=The connection to service created from an endpoint was invalidated from this process.}}}
In addition, several crash logs for RemotePlayerService are generated, showing my app as the parent process.
This issue is 100% repeatable. No matter how I load the queue, whether it’s catalog or library content, any variation I can think of all fails like this.
I really hope this can be fixed before 26.3 comes out, otherwise my app will be totally unusable. 😅
Hi everyone,
I’ve encountered an issue where using a popover inside the toolbar of a Catalyst app causes a crash on macOS 26 beta 5 with Xcode 26 beta 5. Here’s a simplified code snippet:
import SwiftUI
struct ContentView: View {
@State private var isPresentingPopover = false
var body: some View {
NavigationStack {
VStack {
}
.padding()
.toolbar {
ToolbarItem {
Button(action: { isPresentingPopover.toggle() }) {
Image(systemName: "bubble")
}
.popover(isPresented: $isPresentingPopover) {
Text("Hello")
.font(.largeTitle)
.padding()
}
}
}
}
}
}
Steps to reproduce:
Create a new iOS app using Xcode 26 beta 5.
Enable Mac Catalyst (Match iPad).
Add the above code to show a Popover from a toolbar button.
Run the app on macOS 26, then click the toolbar button.
The app crashes immediately upon clicking the toolbar button.
Has anyone else run into this? Any workarounds or suggestions would be appreciated!
Thanks!
Why is the WiFiAware framework not importable in Mac Catalyst? Are there any plans to support Wi-Fi Aware technology on Mac Catalyst in the future?
When building our project for Mac Catalyst with Xcode 26.2, we get this warning almost a hundred times, once for every object file:
directory not found for option '-L/var/run/com.apple.security.cryptexd/mnt/com.apple.MobileAsset.MetalToolchain-v17.3.48.0.UZtKea/Metal.xctoolchain/usr/lib/swift/maccatalyst'
Somehow, every Link <FileName>.o build step got the following parameter, regardless if the target contained Metal files or not:
-L/var/run/com.apple.security.cryptexd/mnt/com.apple.MobileAsset.MetalToolchain-v17.3.48.0.UZtKea/Metal.xctoolchain/usr/lib/swift/maccatalyst
The toolchain is mounted at this point, but the directory usr/lib/swift/maccatalyst doesn't exist.
When building the project for iOS, the option doesn't exist and the warning is not shown.
We already check the build settings, but we couldn't find a reason why the linker is trying to link against the toolchain here.
Even for targets that do contain Metal files, we get the following linker warning:
search path '/var/run/com.apple.security.cryptexd/mnt/com.apple.MobileAsset.MetalToolchain-v17.3.48.0.UZtKea/Metal.xctoolchain/usr/lib/swift/maccatalyst' not found
Is this a known issue? Is there a way to get rid of these warnings?
Using SwiftIUI with CommandGroup for iPad app on Xcode Version 26.2 (17C52). I tried to test on Mac Catalyst. Output view is iPad size but my SwiftUI view is small on the left.
I tried to override the frame size used but none of the suggested ways compiled. Used both "Scaled for iPad" and "Optimized for Mac" in deployment Info with same results.
I’m exploring macOS development, comparing Mac Catalyst apps vs native AppKit/SwiftUI apps.
What are the main limitations of Catalyst today?
In what scenarios is a native AppKit or SwiftUI app unavoidable?
Any insights are much appreciated — I’m trying to understand when Catalyst is sufficient and when going native is worth the extra effort.
I have a SwiftUI-based universal app which creates a file that it stores in documentsDirectory. On iOS/iPadOS, this file is stored in the application's Documents directory and is accessible via the Files app.
On MacCatalyst, this operation does the same thing — it creates the file and stores it in ~/Library/Containers/<app directory>/Data/Documents. However what I want is for the document to be stored in ~/Documents, so that it is easily accessible to the user.
How can I do that? I'd like it to occur without (for example) having to show a SaveFile panel...
I am trying to port my sandboxed macOS app completely over to iOS using a Catalyst target and SwiftUI.
There appears to be an issue when trying to drag to the Finder in Catalyst (and in SwiftUI in General). For some reason, the Finder will not accept multiple file drops, only a single file.
On my macOS (non-Catalyst AppKit target), I overcame this by dropping multiple files to a UTType of .folder, and the OS accepted the folder. This workaround is not available for iOS because .folder is a macOS-only option.
I have a test app to illustrate the issue. Hopefully someone can help.
Download Test App
Hi everyone!
I've encountered an issue on Mac Catalyst: using the latest inspector modifier causes abnormal Sidebar and Columns state in NavigationSplitView.
Sample Code:
struct ContentView: View {
@State private var isPresented = false
var body: some View {
NavigationSplitView {
List {
ForEach(0..<20, id: \.self) { item in
Text("Item \(item)")
}
}
} content: {
List {
ForEach(0..<20, id: \.self) { item in
Text("Item \(item)")
}
}
} detail: {
List {
}
}
.inspector(isPresented: $isPresented) {
Form {
}
}
}
}
Steps to reproduce:
Xcode 16 beta 7, create a new iOS project
Paste the code above
Enable Mac Catalyst
Run on Mac (macOS 15 beta 9)
Press Command+N three times to open 3 new windows
Click the Sidebar Toggle button
The issue occurs (see screenshot below)
Through testing, I found that as long as the inspector modifier is attached, the issue occurs.
Also, the problem only appears in the 3rd and subsequent newly opened windows—the first two windows work as expected.
FB20061521
Hello, I'm wondering if there is a way to prevent a previously-Universal Mac Catalyst app from being available to Intel devices? I can't identify a mechanism that works from build to submit to review.
Topic:
App Store Distribution & Marketing
SubTopic:
App Store Connect
Tags:
Universal Apps
Mac Catalyst
Sidebars for mac Catalyst apps running with UIDesignRequiresCompatibility flag render their active items with a white bg tint – resulting in labels and icons being not visible.
mac OS Tahoe 26.1 Beta 3 (25B5062e)
FB20765036
Example (Apple Developer App):
I have a Catalyst app on the App Store and I'm starting to get messages from users that the popover bubbles all over the app are without content. I see the error locally as well, but I don't know how to fix it.
I get the following warning in XCode when opening a popup:
UIScene property of UINSSceneViewController was accessed before it was set.
On macOS 15.2, any Mac Catalyst project that does not support portrait iPad orientation will no longer be able to successfully show the contents of any popover controls. This does not appear to be a problem on earlier versions of macOS and it only affects Mac Catalyst builds, not "Designed for iPad" builds.
STEPS TO REPRODUCE
Create a project that utilizes Mac Catalyst.
Create a simple button that shows a popover with simple content.
Remove Portrait as a supported orientation.
Run the project on macOS 15.2 as a Mac Catalyst build. Note that the content inside the popover is not shown the popover is shown.
Run the project as Designed for iPad. Note that the popover content shows correctly.
I have an app for macOS that is built using Mac Catalyst. I need to perform some background processing. I'm using BGProcessingTaskRequest to schedule the request. I have also integrated CKSyncEngine so I need that to be able to perform its normal background processing.
On iOS, when the user leaves the app, I can see a log message that the request was scheduled and a bit later I see log messages coming from the actual background task code.
On macOS I ran the app from Xcode. I then quit the app (Cmd-q). I can see the log message that the request was scheduled. But the actual task is never run. In my test, I ran my app on a MacBook Pro running macOS 26.0. When I quit the app, I checked the log file in the app sandbox and saw the message that the task was scheduled. About 20 minutes later I closed the lid on the MacBook Pro for the night. I did not power down, it just went to sleep. Roughly 10 hours later I opened the lid on the MacBook Pro, logged in, and checked the log file. It had not been updated since quitting the app. I should also mention that the laptop was not plugged in at all during this period.
My question is, does a Mac Catalyst app support background processing after the user quits the app? If so, how is it enabled?
The documentation for BGProcessingTaskRequest and BGProcessingTask show they are supported under Mac Catalyst, but I couldn't find any documentation in the Background Tasks section that mentioned anything specific to setup for Mac Catalyst.
Running the Settings app and going to General -> Login Items & Extension, I do not see my app under the App Background Activity section. Does it need to be listed there? If so, what steps are needed to get it there?
If this is all documented somewhere, I'd appreciate a link since I was not able to find anything specific to making this work under Mac Catalyst.
Topic:
App & System Services
SubTopic:
Processes & Concurrency
Tags:
CloudKit
macOS
Mac Catalyst
Background Tasks
I have a Catalyst app ('container') which hosts an embedded AUv3 Audio Unit extension ('plugin'). This used to work for years and has worked with this project until a few days ago.
it still works on iOS as expected
on MacOS the extension is never registered/installed and won't load
extension won't show up with AUVal
seems to have stopped working with the 26.1 XCode update
I'm fairly certain the problem is not code related (i.e. likely build settings, project settings, entitlements, signing, etc.)
I have compared all settings with another still-working project and can't find any meaningful difference
(I can't request code-level support because even the minimal thing vastly exceeds the 250 lines of code limit.)
How can I debug the issue? I literally don't know where to start to fix this problem, short of rebuilding the entire thing and hope that it magically starts working again.