We have updated our cross-platform applications to support iOS 18 and are in the final stages of releasing versions built with MacCatalyst. After merging the MacCatalyst changes with those for iOS 18, we are now required to build the app using Xcode 16. However, since transitioning to Xcode 16, the app builds successfully but crashes immediately on startup with the following error:
dyld[45279]: Symbol not found: _$sSo22VNFaceLandmarkRegion2DC6VisionE16normalizedPointsSaySo7CGPointVGvg
Referenced from: <211097A0-6612-3A9A-80B5-AE12915EBA2A> /Users/***/Library/Developer/Xcode/DerivedData/DM_iOS_Apps-gzpzdsacfldxxwclyngreqkbhtey/Build/Products/Debug-maccatalyst/MyApp.app/Contents/Frameworks/Filters_MyApp.framework/Versions/A/Filters_MyApp
Expected in: <50DB755E-C83C-3FC7-A0BB-9C4DF9FEA374> /System/Library/Frameworks/Vision.framework/Versions/A/Vision
This crash occurs only when building the app with Xcode 16 for MacCatalyst on macOS 14.6.1. On iOS and macOS 15, it functions as expected, and it also worked prior to the iOS 18 changes, which are independent of the Vision framework code, when building with Xcode 15.
Here are the environment details where the error occurs:
Xcode Version: Xcode 16.0 (16A242d)
macOS Version: macOS Sonoma 14.6.1
And the setup where it works:
Xcode Version: Xcode 16.0 (16A242d)
macOS Version: macOS Sequoia 15.0
Additionally, attempting to implement a workaround using pointsInImage(imageSize:) resulted in a similar issue, where the symbol for this method is also missing.
Is this a known issue? Are there any workarounds or fixes available?
We have already submitted this issue as feedback (FB15164375), along with a demo project to illustrate the problem.
Mac Catalyst
RSS for tagStart building a native Mac app from your current iPad app using Mac Catalyst.
Posts under Mac Catalyst tag
108 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
Hello,
I have a macOS Catalyst app that I now began updating and building against the iOS 18/macOS Sequoia SDKs. Most things appear to be working just fine as before, apart from my NSToolbar.
At the root of my app I am presenting a UISplitViewController which gets a custom SidebarViewController and a UITabBarController as its viewControllers.
Then at same point in the apps lifecycle the UITabBarController presents another ViewController modally. I then associate the controllers window with a custom NSToolbar like this:
let toolbar = NSToolbar(identifier: "mainToolbar")
toolbar.displayMode = .iconAndLabel
toolbar.delegate = self
toolbar.allowsUserCustomization = false
titleBar.toolbarStyle = .automatic
titleBar.titleVisibility = .hidden
titleBar.toolbar = toolbar
I also disable automatic NSToolbar hosting via: https://developer.apple.com/documentation/uikit/uinavigationbardelegate/3987959-navigationbarnstoolbarsection (returning .none).
Now all of this worked fine on macOS Sonoma and previous versions but on Sequoia my custom toolbar refuses to show up.
My suspicion is that is has something to do with the new tab and sidebar behaviour introduced with the new SDKs (https://developer.apple.com/documentation/uikit/uinavigationbardelegate/3987959-navigationbarnstoolbarsection).
For now within my UITabBarController I was able to revert to the old look using:
if #available(iOS 18.0, *) {
mode = .tabSidebar
sidebar.isHidden = true
isTabBarHidden = true
}
This result in a look similar to the previous macOS version but my NSToolbar unfortunately remains hidden.
Is there an easy fix for this? Since I am a solo developer I would prefer to spend my available resources currently on other features and adopt the new tab/sidebars a couple months down the line.
Appreciate any help and hints, thanks!
There used to be a toolbar here on the right side. ↑
I'm using the same code to authenticate using passkeys on iOS and macOS. On iOS (simulator, on-device, and deployed with TestFlight), I have no issues registering or authenticating with a passkey. On macOS using Catalyst, when I attempt to authenticate with a passkey (ASAuthorizationController#performRequests), I see the following error:
Error Domain=com.apple.AuthenticationServices.AuthorizationError Code=1004 "Application with identifier TEAMID.com.bundle is not associated with domain bundle.com" UserInfo={NSLocalizedFailureReason=Application with identifier TEAMID.com.bundle is not associated with domain bundle.com}
I've double-checked my apple-app-site-association file is being served from the associated domain, and I've double-checked that the Apple CDN is also returning that same association file with webcredentials for my team/bundle.
Any ideas why it would succeed in iOS environments but fail under macOS with Catalyst?
I have a Catalyst app that plays audio via AVQueuePlayer, and I'd like to use the system play/pause key (F8 on my MacBook Pro keyboard) to play and pause it. It doesn't seem to work automatically, and if I hook up a UIKeyCommand using UIKeyInputF8, it works with Fn-F8, not F8 on its own.
It does seem to work in Overcast's Mac app, but I think that's an iPad app for Mac, not Catalyst, so it's probably going through whatever system pathway that the Lock Screen controls would be using on iOS.
How do I make this work on Catalyst?
The title says it all, I'm using SwiftUI for multiplatform app, and I'm using ScrollView in it.
My app has player bar which tracks the AVPlayer's current time. I made it using .offset(y:).
The problem here is that whenever I change offset, the scroll gesture suddenly doesn't work on macOS.
Video link: https://streamable.com/euzuwk
But weirdly, it works on Mac Catalyst version.
Video link: https://streamable.com/oq01mt
The source code is on GitHub.
I tried using Animation, but it made the player bar and music out of sync.
So right now I made a publisher based on AVPlayer's addPeriodicTimeObserver and receiving the time from AVPlayer but now the scroll doesn't work as expected.
Hello,
I am developing a Mac application via Mac Catalyst and encountering an issue with WKWebView. Specifically, I'm loading a webpage (e.g., https://translate.google.com) in WKWebView, but when I press the copy button on the page, the content doesn't actually copy to the clipboard.
I've attempted modifying the UserAgent without any success. Here is the relevant part of my code:
override func viewDidLoad() {
super.viewDidLoad()
let config = WKWebViewConfiguration()
config.preferences = WKPreferences()
config.defaultWebpagePreferences.preferredContentMode = .desktop
let webView = WKWebView(frame: .zero, configuration: config)
webView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(webView)
webView.scrollView.showsVerticalScrollIndicator = false
webView.backgroundColor = UIColor.white
webView.scrollView.backgroundColor = UIColor.white
webView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
webView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
webView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
webView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
if let url = URL(string: "https://translate.google.com") {
let req = URLRequest(url: url)
webView.load(req)
}
}
UITextView erroneously overrides string attributes when applying spellchecker annotation attributes.
It doesn't need any particular setting. Default UITextView instance with attributed text
let textView = UITextView(usingTextLayoutManager: true)
textView.spellCheckingType = .yes
Once spellcheck attributes get applied, other attributes like foreground color get applied to the misspelled words. This behavior happens only on Mac Catalyst, and started to appear on macOS 14 or newer.
Please check the Xcode project that demonstrates the issue https://github.com/user-attachments/files/16689336/TextEditor-FB14165227.zip
Open TextEditor project
Select "My Mac (Mac Catalyst)" build destination
Run the project. A window with a text area should appear
Select the whole text (either using mouse or keyboard command+a)
Observe how foregroundColor changes to text (this is the issue)
That eventually led to crash 💥
This bug is reported to Apple FB14165227
We use the triple column layout and when running our app under Sequoia Beta, the Secondary view controller's navigation bar is not shown initially. If a view is pushed inside the secondary (which contains a UINavigationController), and then popped again, the navigation bar is shown.
In AppKit, I can implement NSApplicationDelegate methods for application:openFiles: and such.
However, I have not found something similar when using Catalyst - I cannot set the NSApplicationDelegate, and the UIApplicationDelegate methods I have tried are not called when I try dragging a file to the app icon (the icon lights up, so I believe I have configure it properly).
Does anyone know how to do that / have a sample that works?
Thanks.
Hi folks, I'm struggling with an issue on MacCatalyst. I'm using a dynamic menu that is supposed to show the current state of a setting (state = .on / .off). The UIDeferredMenuElement works great on iOS, the closure is called on each display of the (context) menu.
On MacCatalyst however - where I use the menu as a submenu in the main menu - the closure is called only once on first menu display. The system seems to show a cached menu item even though I'm using UIDeferredMenuElement.uncached.
Here's the relevant code:
func getMenuElement() {
let element = UIDeferredMenuElement.uncached { completion in
let modeString = mode.myLocalizedDescription
let trackingMode = <current setting>
let mode = <menu item setting option>
let state = trackingMode == mode ? .on : .off
let action = UIAction(title: modeString,
image: <image>,
state: state) { _ in
viewController.setUserTrackingMode(mode)
}
completion([action])
}
return element
}
Any ideas how to trick the system into generating the dynamic menu item on each menu display?
I have an iOS app I've added Catalyst support to. It is a UIDocument based app using a UIDocumentBrowserController subclass.
When the app launches a file browser SHOULD appear in front of the app window. And if I have launched the app for the first time or it was force quit the last time it was used this works as intended.
However if I open a document and then quit the app either by closing the app window or choosing AppMenu -> Quit then launch the app again I get an error dialog that only Says "No document could be created" with an okay button. When you click okay the app window comes to the front covering the document browser creating an app killing problem that is confusing for users. Yes they can go to file -> New or File -> Open Document but the situation is very confusing.
I have tried returning false for these functions in my AppDelegate:
func application(_ application: UIApplication, shouldSaveApplicationState coder: NSCoder) -> Bool {
return false
}
func application(_ application: UIApplication, shouldRestoreApplicationState coder: NSCoder) -> Bool {
return false
}
func application(_ application: UIApplication, shouldSaveSecureApplicationState coder: NSCoder) -> Bool{
return false
}
And I've added NSQuitAlwaysKeepsWindows = No in my info.plist and the problem persists.
I have set a break point in my document's init(fileURL:) function but it is not called so I have no idea what document is attempting to be created or how to stop it.
A have the application with iOS and Mac Catalyst versions and I need to make a cloud client for the app's documents. FileProvider would be the great choice for this feature, but I can't believe it doesn't support Mac Catalyst.
At this moment I'm almost certain that NSFileProviderReplicatedExtension does not support Mac catalyst officially. And if it so, It would be great to hear the exact status and future plans if any.
Unofficially, I managed to run it.
I switched the extension's target Supported Destination from Mac Catalyst to Mac and it started to compile. This move seems legit to me.
But domain also had to be created, and this part was a way trickier. I've added new bundle to host app(iOS and catalyst), but with supported platform - macOS in build settings. There I created an NSObject subclass DomainManager which calls NSFileProviderManager's addDomain method in its createDomainIfNeeded(), which is also exposed in public extension to NSObject - a kind of "informal protocol"
The catalyst app creates bundle by name and loads principal class (DomainManager), but as NSObject reference, and then calls createDomainIfNeeded() method on it.
The location defined by domain appears in Finder sidebar, and the dataless item "a file" appears in this location, as defined by stub implementation in the extension enumerator method. This means file system instantiated the extension instance under Mac catalyst and called the protocol method on it. I.e. it seem to work.
But the question is whether this solution is stable and legit for the App Store distribution. Or is it pandora box with unforeseeable consequences for user data? Thanks in advance.
I have a Mac Catalyst app bundle built from Rust. I am able to execute this bundle from my M2 Mac-Mini. I am wondering how might I go about creating a proper IPA archive in order to install to my iOS/iPadOS devices.
I am using the following code to generate and sign the app bundle:
cd "${APPDIR}/"
/usr/bin/codesign -s "Apple Development: <ID>" -fv ./counter.app
cd ./counter.app
zip -r ../counter.ipa *
I then use cfgutil to try to install to my iPhone that is plugged into my Mac-Mini:
cfgutil -v install-app ./counter.ipa
I receive the following error when trying to install:
Waiting for the device [1/4] [*******************************************] 100%
cfgutil: error: Information about an app could not be read.
(Domain: ConfigurationUtilityKit.error Code: 404)
"install-app" failed on <>'s iPhone (ECID: <>).
--- Summary ---
Operation "install-app" failed on 1 devices.
The contents of the app bundle before signing:
counter.app/
- Geneva.ttf
- counter
- Info.plist
Contents of Info.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleIdentifier</key>
<string>com.example.counter</string>
<key>CFBundleDisplayName</key>
<string>counter</string>
<key>CFBundleName</key>
<string>counter</string>
<key>CFBundleExecutable</key>
<string>counter</string>
<key>CFBundleVersion</key>
<string>0.1.0</string>
<key>CFBundleShortVersionString</key>
<string>0.1.0</string>
<key>CFBundleDevelopmentRegion</key>
<string>en_US</string>
<key>UILaunchStoryboardName</key>
<string></string>
<key>LSRequiresIPhoneOS</key>
<true/>
</dict>
</plist>
Is there anything I'm doing wrong in signing and/or creating the IPA archive? Or perhaps I am missing something in the bundle itself?
We maintain a device driver for macOS. This consists of a bunch of components including a Launch Agent, a (Cocoa/AppKit) status bar item app, and a "main" windowed UI app. These all communicate with each other via XPC using the "low level" XPC APIs (libxpc). The launch agent registers a named Mach XPC service, and the two apps connect to it when they launch.
Last year, we had an overhaul of the main UI app as we wanted to add a bunch of features. In the process we decided to switch it from Cocoa/AppKit to Mac Catalyst/UIKit as we were also contemplating porting the driver to iPadOS in future; plus, UIKit is a little simpler and I'm not a great UI programmer, so any simplification is welcome.
This has worked OK so far, but in our attempt to upgrade our build toolchain from Xcode 15.2 to Xcode 15.4 we found that the Catalyst app would no longer build. Apparently the xpc_connection_create_mach_service() and xpc_connection_set_peer_code_signing_requirement() functions are no longer available as of the Mac Catalyst SDK included with Xcode 15.3. This makes it impossible for the app to connect to the launch agent's XPC service.
A few things to note:
These functions were never deprecated, so we did not have their impending removal on our radar.
It seems they actually used to be available in the iOS SDK and were removed from that, so Mac Catalyst is effectively collateral damage. I don't think these would ever have been usable in apps on the iOS App Store, so perhaps they were removed from the iOS SDK ahead of support for notarised iOS app distribution.
So it looks like they might have been removed from Mac Catalyst SDK by accident? I therefore filed a bug about this - FB13929309 - about 6 weeks ago. Reinstating the functions for Mac Catalyst would seem like a very straightforward fix, but I've not had a hint of feedback on the report.
I guess my forum question comes down to this: Is Mac Catalyst considered a platform for building macOS apps in its own right? Or are we "holding it wrong" and should we only treat it as a way of tweaking Mac ports of iOS/iPad-first apps? Should we expect APIs to disappear from the Mac Catalyst SDK with zero notice?
We can still build with Xcode 15.2 for the moment, and the app built this way runs fine up to and including the macOS 15 beta. But thanks to the limited forward and backward compatibility schedule for Xcode we can't stay on old Xcode for long We're also planning to make some feature changes to the app in the near future, and I don't want to be investing in an app built on a platform with no future. I'd rather port the app back to Cocoa/AppKit before adding features if that's the case.
So with SKStoreReviewController now deprecated... I'm wondering what API is recommended for UIKit apps?
I am running into an issue with UITabBarController in a Catalyst app when building under Xcode 16 and running on macOS 15.
If a UITabBarController is used, the tabs are presented in an unwanted title/toolbar at the top of the window. If you have an app where your views run to the top of the window, this can obscure the content and controls that are near the top.
I created a sample application that is attached to the Feedback record (FB14293963). When building under Xcode 15, this is what the app looks like:
Under Xcode 16, it looks like this:
Beyond this simple example, using UITabBarController in a presented view controller can result in the tabs not showing at all. Also, If you switch the view in the main window to something that isn't a UITabBarController, the tabs still remain at the top.
This seems to stem from the tab bar/sidebar changes for iPadOS 18. While this approach can work for simpler apps, it may not work well at all for more complex apps and there really needs to be a way to opt out of this behavior so apps where it is not suited for can still take advantage of features in iPadOS/Catalyst 18.
Has anyone discovered a workaround or way to disable the new tab bar behavior with having to write their own version of UITabBarController?
I have the same issue. It was reported to Apple in November, 2023. Anyone else see this as a huge issue?
Our apps can currently be installed on Apple Silicon Macs via the iPad app on Mac feature (“Designed for iPad”). Now we are working on “proper” (universal) Catalyst-based Mac apps that will be available on the Mac App Store.
How does the transition work for users that currently have the iPad version installed? Will they automatically update to the Mac Catalyst app once it’s available, or do they need to re-install the app from the Mac App Store?
Prior to Sequoia, Mac Catalyst Apps worked fine when using group folders that started with group. They now get an alert that the Mac Catalyst app is trying to access data from other applications. This may also impact some SwiftUI developers.
According to this the documentation for the App Group Entitlements entitlement, on macOS we should begin use the Team Identifier instead of group.
Should Mac Catalyst follow the macOS or iOS rules for com.apple.security.application-groups? If they should need to follow the macOS rules now, that creates several issues for developers. We would now need separate build targets to pick up the different Entitlements files. More distressing is that we would need to do some kind of migration process to get our files to the new location. There wouldn't be a transparent way to do so where the user wasn't warned about the application accessing files that don't belong to it.
Any clarification on what Mac Catalyst developers should be doing to prepare for Sequoia would be greatly appreciated.
I have a UITableView that displays a Group/Note hierarchy analogous to a Finder Folder/Files hierarchy. I have implemented Drag and Drop such that if I drag a Note to the Finder Desktop an HTML file is created of the Note, and if I drag a Group to the Finder Desktop a Text file is created of the Group's title. Here is the Helper Dragging extension that I've implemented:
//
// Model+Dragging.swift
//
/*
Abstract:
Helper methods for providing and consuming drag-and-drop data.
*/
import UIKit
import MobileCoreServices
// Conditionalize Drag and Drop so it is not in iOS target.
#if targetEnvironment(macCatalyst)
extension Model {
/**
A helper function that serves as an interface to the data model,
called by the implementation of the `tableView(_ canHandle:)` method.
*/
func canHandle(_ session: UIDropSession) -> Bool {
// In order to enable dragging all text type files changed the class
// loadable objects from NSString to my custom TEXTClass.
return session.canLoadObjects(ofClass: TEXTClass.self)
}
/**
A helper function that serves as an interface to the data model, called
by the `tableView(_:itemsForBeginning:at:)` method.
*/
func dragItems(for indexPath: IndexPath) -> [UIDragItem] {
let itemProvider = NSItemProvider()
let item = self.getDisplayItem(for: indexPath.row)
if item is Note {
let note:Note = item as! Note
let html = note.noteHTML
let data = html?.data(using: .utf8)
// Drag to finder creates an html file.
itemProvider.suggestedName = note.title + ".html"
itemProvider.registerDataRepresentation(forTypeIdentifier: kUTTypeData as String,
visibility: .all) { completion in
completion(data, nil)
return nil
}
} else {
let group:Group = item as! Group
let title = group.title
let data = title?.data(using: .utf8)
// Drag to finder creates a text file.
itemProvider.suggestedName = group.title + ".text"
itemProvider.registerDataRepresentation(forTypeIdentifier: kUTTypeData as String,
visibility: .all) { completion in
completion(data, nil)
return nil
}
}
return [
UIDragItem(itemProvider: itemProvider)
]
}
}
#endif
I would now like to change the result of dragging a Group to the Finder. Instead of creating a Text file from the drag data, I would like to create a Folder containing the Group's Notes.
Note: I am unconcerned with the task of assembling the Group/Notes hierarchies as Folder/Files hierarchies because I already have implemented such previously as a menu export command. My concern is where and how I can communicate it to the Finder in the Drag and Drop process.
As a first step I thought I would simply create an empty folder from the drag of a Group. So far, none of my experiments have been successful. Every variation of itemProvider.registerDataRepresentation(forTypeIdentifier: or itemProvider.registerFileRepresentation(forTypeIdentifier: or registerItem(forTypeIdentifier:loadHandler: that I have tried has failed to produce anything but empty TEXT files, if they worked at all.
It is my understanding that itemProviders may provide directories instead of files, but I have been unable to find any examples of such.
My problem may be a lack of understanding of the syntax and usage of the NSItemProvider.LoadHandler completion block.
Any Swift examples on point would be greatly appreciated!