A Mac Catalyst App Creates an AppKit Bundle Plugin in which @available does not work。
In AppKit Bundle Plugin, there is not watchOS and iOS version can not be higher than 28, but the log has been output.
if (@available(watchOS 18.0, *)) {
NSLog(@"bundle is available watchOS");
}
if (@available(iOS 28.0, *)) {
NSLog(@"bundle is available iOS");
}
demo link: https://pan.baidu.com/s/1s_5qmsL6Bh-df3A1PfD0OA
Extracted code: 5ndj
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
If I have a Catalyst app with a WKWebView and I select text, I can drag forward to extend the selection, but I can't reduce the length of the selected range by dragging backwards. I've reproduced this in a trivial sample app.
Is there some property I need to set somewhere?
I've filed this as FB15645411.
Hi,
Firstly: The whole question is about MacCatalyst (in IOS it works as intended)
In my Maccatalyst app I want to share Userdefaults between app and widget. I have added an app group to the widget and the app and have set up Userdefauls accordingly.
Here is the problem:
Xcode claims that the app group should start with "group.***" because Catalyst is based on iOS. If I do so, my Catalyst app rises the "App wants to access data from other apps" requester on EVERY launch. So, I can't use it in production. Even if I would accept the requester, the widget isn't able to access the defaults at all because it does not rise that requester, but silently ignores the access.
In contrast, if I setup the app group name with our TeamID (instead of group.*) then the requester vanishes, but Xcode does not accept it, issuing a warning and displaying the app group in red. I don't think this is advisable 'state' for production code. Even then widget can't see the data either.
What is the recommended way of sharing Userdefaults between Catalyst app and Catalyst Widget (not the iOS widget which displays the "open on iPhone warning" when clicked) on macOS ?
Thanks
I am using a Mac Catalyst with SwiftUI for our document-based app with DocumentGroup. The issue is that when we create a new document or open an existing one, the opened view is completely blank. It is only blank/empty when the "Optimzie for Mac" is checked. If it is "Scaled t oMatch iPad", then it works well.
Xcode 16.1
macOS 15.1
struct DocumentGroupTestApp: App {
var body: some Scene {
DocumentGroup(newDocument: WritingAppDocument()) { file in
TestView() // it is empty when it gets opened. It does not work if the option "Optimize for Mac" is checked. If it is scale iPad, then it works.
}
}
}
struct TestView: View {
var body: some View {
Text("Hello, World!")
}
}
I have a Catalyst app that uses popovers frequently, and I'd love to have them stay active when the app loses focus. It appears this is controlled in a native AppKit app via NSPopover.Behavior. Is this functionality exposed somewhere in Catalyst?
I couldn't find any documentation related to if WebRTC is supported in macOS/macOS Catalyst, but all my tests related to that fail.
I also experience the same as in this post:
https://developer.apple.com/forums/thread/695871?login=true
Meanwhile in iOS it works well.
As of macOS Sequoia 15.1 (and probably earlier), in System Settings under Accessibility -> Display, there's a Text Size option that looks an awful lot like Dynamic Type on iOS:
I have an iOS app with robust support for Dynamic Type that I've brought to the Mac via Catalyst. Is there any way for me to opt this app into supporting this setting, maybe with some Info.plist key?
Calendar's Info.plist has a CTIgnoreUserFonts value set to true, but the Info.plist for Notes has no such value.
I have a Catalyst app that supports multiple scenes / windows. It has one "main" window type and lots of other secondary windows that can be opened. I'm using the system window restoration functionality via NSQuitAlwaysKeepsWindows to restore windows with their user activity data after the app is quit and restarted.
Normally, this works great. If I open my app, change the size and position of my window, quit, and reopen it, the window size and position comes back as expected. But if I close the window using the red stoplight button and then click the app icon to bring it back, it comes back at the default position and size.
This isn't how other system apps work - if I close the system Calendar app with the stoplight button, it comes back at the same size and position. How do I get this behavior with my Catalyst app? Is there some identifier property I need to set somewhere? I don't see such a property on UISceneConfiguration.
If it matters, I'm using the configurationForConnectingSceneSession method to configure my windows when they open, instead of setting it up in the Info.plist.
Hello,
I've just enabled Mac Catalyst for my already available and working iPad.
When trying to build for Mac Catalyst I get this error in a subclass of NSURL.
required initializer .... must be provided by subclass of NSURL
Ok. So I add that, but then it tells me the Mac Catalyst doesn't support NSPasteboard.
`NSPasteboard is unavailable in Mac Catalyst'
This seems like a catch-22!
I've tried variations like
#if canImport(AppKit) && !targetEnvironment(macCatalyst)
required init?(pasteboardPropertyList propertyList: Any, ofType type: NSPasteboard.PasteboardType) {
fatalError("init(pasteboardPropertyList:ofType:) has not been implemented")
}
#endif
But not having any luck.
Hello, my app uses vibrancy effects thanks to SwiftUI's materials and hierarchical shape style. While they work flawlessly on iOS and iPadOS, on Mac Catalyst they seem to be pretty broken.
I'm attaching some screenshots.
iPad
Mac
This is the same code, with the same background behind the material. The colors are already pretty different, but my concern is about the text, which clearly looks broken
Here a sample code:
HStack(spacing: 0) {
VStack(alignment: .leading, spacing: 2) {
Text(event.label)
.font(.subheadline.weight(.semibold))
.foregroundStyle(.secondary)
Text(event.info(for: currentDestination))
.font(.system(.title2, design: .rounded, weight: .semibold))
.foregroundStyle(.primary)
}
Spacer(minLength: 0)
InfoIcon(isCustom: event.isCustomIcon, icon: event.icon, renderingMode: .palette, size: iconSize)
.font(.body.weight(.semibold))
}
.padding(.horizontal, 24)
.padding(.vertical, 12)
.background(.quaternary, in: .rect(cornerRadius: 16, style: .continuous))
.clipShape(.rect(cornerRadius: 16, style: .continuous))
.padding(.all, 16)
.background(.ultraThinMaterial, in: .rect)
My application suddenly started crashing on launch when I target "My Mac - designed for iPad." But only after the first build from scratch, which runs once. All subsequent runs crash with:
dyld[90869]: Symbol not found: _OBJC_CLASS_$_AVPlayerView
Referenced from: <D566512D-CAB4-3EA6-9B87-DBD15C6E71B3> /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Debugger/libViewDebuggerSupport.dylib
Expected in: <4C34313C-03AD-32EB-8722-8A77C64AB959> /System/iOSSupport/System/Library/Frameworks/AVKit.framework/Versions/A/AVKit
I don't use AVPlayerView anywhere in my application. A file-contents search of the entire source tree doesn't turn it up either. The application doesn't even get to the point of instantiating the app object, so none of my code is involved.
If I switch the target to my iPhone, it will build and run repeatedly. If I then switch back to "My Mac," it will build and run once... and then crash every time.
Further research shows that this only happens in Debug builds.
This is a major issue right now because iOS 18 broke authentication certificates (thus HTTPS), so anyone writing or debugging an app that needs network functionality must use HTTP on localhost. In my case, I'm dead in the water because I can't debug on my local machine.
Has anyone seen something like this before? I can find no reference to anything like it.
Hello,
I am adding support for Mac Catalyst to my project's existing iOS target.
When running a TestFlight build, the app crashes at launch on macOS 14 but not on 15. The crash log is always the same and I am struggling to figure it out.
Here is the log:
crashlog.crash
Hello,
I am adding support for Mac Catalyst to my project's existing iOS target.
When using a TestFlight build, the app crashes at launch on macOS 14 (from what we are observing) but not on macOS 15. The crash log is always the same and I am struggling to figure it out.
Here is the log:
crashlog.crash
I have an iOS app that relies on dynamic text size such that all fonts in the app respect the user's setting of Text Size in the iOS Settings app.
This app also runs on macOS via Mac Catalyst. But until macOS 14 Sonoma, there was no Text Size setting in the macOS Settings app. But even as of Sonoma, the Text Size setting isn't usable by 3rd party apps. And Sequoia doesn't seem to change that.
As a work around, my Mac Catalyst app provides its own Text Size setting. I was able to make it work by providing my own UIApplication subclass and overriding preferredContentSizeCategory. Under macOS 12 to macOS 14, this workaround works just fine and all fonts in the app created with code such as UIFont.preferredFont(forTextStyle:) gives appropriately sized fonts based on the overridden content size category.
However, this workaround stopped working with macOS 15 Sequoia. I've also tried code such as:
self.window.traitOverrides.preferredContentSizeCategory = myCustomSizeCategoryValue
and
self.window.maximumContentSizeCategory = myCustomSizeCategoryValue
self.window.minimumContentSizeCategory = myCustomSizeCategoryValue
in the scene delegate but that made no difference.
Is there any way to get code such as UIFont.preferredFont(forTextStyle:) to return an appropriately sized font based on some app provided content size category in a Mac Catalyst app running under macOS 15?
It sure would be nice if Mac Catalyst apps automatically responded to the macOS Text Size setting under Settings -> Accessibility -> Display -> Text Size just like a native iOS app.
I think I've found a bug with SwiftUI TabView selection binding on Mac Catalyst 18.
This code prints to the console when the SceneStorage variable for the TabView selection changes.
If you run the code below on iOS and change the tab, the selection prints to the console indicating the SceneStorage variable has changed.
If you run the code below on Mac Catalyst 18 in Sequoia and change the tab, the selection does not print to the console indicating the SceneStorage variable has not changed.
Looking for input please before I turn this over to Apple code-level support.
//
// ContentView.swift
// tabview-catalyst-issue
//
import SwiftUI
import os.log
enum TabDisplay: String, CaseIterable, Identifiable {
case list
case grid
var id: String { self.rawValue }
}
struct ContentView: View {
@SceneStorage("selectedTabView") var selectedTabView = TabDisplay.list
var body: some View {
VStack {
TabView(selection: $selectedTabView) {
Text("LIST")
.tabItem {
Image(systemName: "list.bullet")
Text("List")
}
.tag(TabDisplay.list)
Text("GRID")
.tabItem {
Image(systemName: "rectangle.split.3x3")
Text("Grid")
}
.tag(TabDisplay.grid)
}
}
.padding()
.onChange(of: self.selectedTabView, perform: { value in
// Added to show that the TabView binding doesn't work in Mac Catalyst 18
print(value)
})
}
}
#Preview {
ContentView()
}
I'm working on replacing an AppKit-based Mac app with one built on Catalyst, and the Catalyst app doesn't seem to be able to read the keychain item that was saved by the old app.
Both apps are using the same bundle ID. The old app uses the old SecKeychain APIs - SecKeychainFindGenericPassword and friends - and the Catalyst app uses the newer SecItemCopyMatching and such. When I try using the new API in the old app to search for the entry, it works, but the exact same code in Catalyst fails.
Here's how I save an item in the old app:
NSString *strItemId = @"my_item_id;
NSString *username = @"user";
const char *userPointer = [username UTF8String];
NSString *password = @"password";
const char *pwPointer = [password UTF8String];
SecKeychainItemRef ref = NULL;
OSStatus status = SecKeychainFindGenericPassword(0, (UInt32)strlen(strItemId.UTF8String), strItemId.UTF8String, 0, NULL, NULL, NULL, &ref);
if (status == errSecSuccess && ref != NULL)
{
//update existing item
SecKeychainAttribute attr;
attr.length = (UInt32)strlen(userPointer);
attr.data = (void *)userPointer;
attr.tag = kSecAccountItemAttr;
SecKeychainAttributeList list;
list.count = 1;
list.attr = &attr;
OSStatus writeStatus = SecKeychainItemModifyAttributesAndData(ref, &list, (UInt32)strlen(pwPointer), pwPointer);
}
else
{
status = SecKeychainAddGenericPassword(NULL, (UInt32)strlen(strItemId.UTF8String), strItemId.UTF8String, (UInt32)strlen(userPointer), userPointer, (UInt32)strlen(pwPointer), pwPointer, NULL);
}
And here's the query code that works in the old app but returns errSecItemNotFound in Catalyst:
NSMutableDictionary *queryDict = [[[NSMutableDictionary alloc]init]autorelease];
[queryDict setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass];
[queryDict setObject:(@"my_item_id") forKey:(__bridge id)kSecAttrService];
[queryDict setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit];
[queryDict setObject:(__bridge id)kCFBooleanTrue forKey:(__bridge id)kSecReturnAttributes];
CFMutableDictionaryRef outDictionary = nil;
OSStatus err = SecItemCopyMatching((__bridge CFDictionaryRef)queryDict, (CFTypeRef *)&outDictionary);
I tried creating a new blank AppKit-based Mac app project in Xcode and gave it the old Mac app's bundle ID, and the SecItemCopyMatching query code above works there. Then I created a new iOS target with Catalyst enabled, also with the same bundle ID, and the query code running there under Catalyst returned errSecItemNotFound. So maybe the issue is something specific to Catalyst?
Is there something I need to do with the Catalyst app to give it access to the old app's keychain entry, besides setting its bundle ID to match the old app?
Hello!
I discovered a bug on Catalyst about a three years ago but it still seems to be not fixed. My bug report number is FB9705748.
The Internet is silent on this so I'm even not sure, perhaps it's only me.
So to the problem. When you display UICollectionViewController or UIViewController that contains UICollectionView, interact with the collection view then dismiss the view controller, the displayed view controller isn't released if dismissal is done through navigation bar item.
The problem occurs only when the run target is My Mac (Mac Catalyst). Everything is fine when you run on iOS or via My Mac (Designed for iPad).
The sample project is uploaded to GitHub. It has a video that shows this strange behavior, see the log for 'deinit' messages.
I did have some workaround to fix this but it stops to work, presumable on the new macOS. Also, chances are that it's not only UICollectionView which initiates the glitch, it's just that I only encounter it with collection views.
I'm trying to build an iOS project in command line via xcodebuild.
OS: Mac OS 15.1 beta
Xcode: Xcode 16
Creating a new iOS project and trying to run xcodebuild results in this error. No other dependencies, no frameworks added.
ld: building for 'iOS', but linking in dylib (/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/lib/libobjc.A.tbd) built for 'macOS macCatalyst zippered(macOS/Catalyst)'
My initial plan was to do this with a VisionOS project, but for some reason, I'm getting errors like this for both platforms and brand new projects.
Any pointers as to what is referencing the MacOS SDK and how I can fix this would be helpful.
Complete log:
/Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild -sdk iphoneos -configuration Release -scheme iphonedummy build CODE_SIGNING_ALLOWED=NO -verbose
User defaults from command line:
IDEPackageSupportUseBuiltinSCM = YES
Build settings from command line:
CODE_SIGNING_ALLOWED = NO
SDKROOT = iphoneos18.0
Prepare packages
ComputeTargetDependencyGraph
note: Building targets in dependency order
note: Target dependency graph (1 target)
Target 'iphonedummy' in project 'iphonedummy' (no dependencies)
GatherProvisioningInputs
CreateBuildDescription
// Removed a block for length.
ExecuteExternalTool /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -v -E -dM -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS18.0.sdk -x c -c /dev/null
// Removed another block for length.
Build description signature: dc5e0c08dfce007b98c7bce87acea5fe
Build description path: /Users/sravankaruturi/Library/Developer/Xcode/DerivedData/iphonedummy-bwpzemojmpkzehhhkxqtjearnxkl/Build/Intermediates.noindex/XCBuildData/dc5e0c08dfce007b98c7bce87acea5fe.xcbuilddata
ClangStatCache /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang-stat-cache /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS18.0.sdk /Users/sravankaruturi/Library/Developer/Xcode/DerivedData/SDKStatCaches.noindex/iphoneos18.0-22A3362-8ec3fe4dca91fa9a941eaa2d5faad0e4.sdkstatcache
cd /Users/sravankaruturi/dev/iphonedummy/iphonedummy.xcodeproj
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang-stat-cache /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS18.0.sdk -o /Users/sravankaruturi/Library/Developer/Xcode/DerivedData/SDKStatCaches.noindex/iphoneos18.0-22A3362-8ec3fe4dca91fa9a941eaa2d5faad0e4.sdkstatcache
ProcessInfoPlistFile /Users/sravankaruturi/Library/Developer/Xcode/DerivedData/iphonedummy-bwpzemojmpkzehhhkxqtjearnxkl/Build/Products/Release-iphoneos/iphonedummy.app/Info.plist /Users/sravankaruturi/Library/Developer/Xcode/DerivedData/iphonedummy-bwpzemojmpkzehhhkxqtjearnxkl/Build/Intermediates.noindex/iphonedummy.build/Release-iphoneos/iphonedummy.build/empty-iphonedummy.plist (in target 'iphonedummy' from project 'iphonedummy')
cd /Users/sravankaruturi/dev/iphonedummy
builtin-infoPlistUtility /Users/sravankaruturi/Library/Developer/Xcode/DerivedData/iphonedummy-bwpzemojmpkzehhhkxqtjearnxkl/Build/Intermediates.noindex/iphonedummy.build/Release-iphoneos/iphonedummy.build/empty-iphonedummy.plist -producttype com.apple.product-type.application -genpkginfo /Users/sravankaruturi/Library/Developer/Xcode/DerivedData/iphonedummy-bwpzemojmpkzehhhkxqtjearnxkl/Build/Products/Release-iphoneos/iphonedummy.app/PkgInfo -expandbuildsettings -format binary -platform iphoneos -additionalcontentfile /Users/sravankaruturi/Library/Developer/Xcode/DerivedData/iphonedummy-bwpzemojmpkzehhhkxqtjearnxkl/Build/Intermediates.noindex/iphonedummy.build/Release-iphoneos/iphonedummy.build/assetcatalog_generated_info.plist -requiredArchitecture arm64 -o /Users/sravankaruturi/Library/Developer/Xcode/DerivedData/iphonedummy-bwpzemojmpkzehhhkxqtjearnxkl/Build/Products/Release-iphoneos/iphonedummy.app/Info.plist
Ld /Users/sravankaruturi/Library/Developer/Xcode/DerivedData/iphonedummy-bwpzemojmpkzehhhkxqtjearnxkl/Build/Products/Release-iphoneos/iphonedummy.app/iphonedummy normal (in target 'iphonedummy' from project 'iphonedummy')
cd /Users/sravankaruturi/dev/iphonedummy
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -Xlinker -reproducible -target arm64-apple-ios18.0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS18.0.sdk -Os -L/Users/sravankaruturi/Library/Developer/Xcode/DerivedData/iphonedummy-bwpzemojmpkzehhhkxqtjearnxkl/Build/Intermediates.noindex/EagerLinkingTBDs/Release-iphoneos -L/Users/sravankaruturi/Library/Developer/Xcode/DerivedData/iphonedummy-bwpzemojmpkzehhhkxqtjearnxkl/Build/Products/Release-iphoneos -F/Users/sravankaruturi/Library/Developer/Xcode/DerivedData/iphonedummy-bwpzemojmpkzehhhkxqtjearnxkl/Build/Intermediates.noindex/EagerLinkingTBDs/Release-iphoneos -F/Users/sravankaruturi/Library/Developer/Xcode/DerivedData/iphonedummy-bwpzemojmpkzehhhkxqtjearnxkl/Build/Products/Release-iphoneos -filelist /Users/sravankaruturi/Library/Developer/Xcode/DerivedData/iphonedummy-bwpzemojmpkzehhhkxqtjearnxkl/Build/Intermediates.noindex/iphonedummy.build/Release-iphoneos/iphonedummy.build/Objects-normal/arm64/iphonedummy.LinkFileList -Xlinker -rpath -Xlinker @executable_path/Frameworks -dead_strip -Xlinker -object_path_lto -Xlinker /Users/sravankaruturi/Library/Developer/Xcode/DerivedData/iphonedummy-bwpzemojmpkzehhhkxqtjearnxkl/Build/Intermediates.noindex/iphonedummy.build/Release-iphoneos/iphonedummy.build/Objects-normal/arm64/iphonedummy_lto.o -fobjc-link-runtime -L/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphoneos -L/usr/lib/swift -Xlinker -add_ast_path -Xlinker /Users/sravankaruturi/Library/Developer/Xcode/DerivedData/iphonedummy-bwpzemojmpkzehhhkxqtjearnxkl/Build/Intermediates.noindex/iphonedummy.build/Release-iphoneos/iphonedummy.build/Objects-normal/arm64/iphonedummy.swiftmodule -Xlinker -dependency_info -Xlinker /Users/sravankaruturi/Library/Developer/Xcode/DerivedData/iphonedummy-bwpzemojmpkzehhhkxqtjearnxkl/Build/Intermediates.noindex/iphonedummy.build/Release-iphoneos/iphonedummy.build/Objects-normal/arm64/iphonedummy_dependency_info.dat -o /Users/sravankaruturi/Library/Developer/Xcode/DerivedData/iphonedummy-bwpzemojmpkzehhhkxqtjearnxkl/Build/Products/Release-iphoneos/iphonedummy.app/iphonedummy
ld: building for 'iOS', but linking in dylib (/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/lib/libobjc.A.tbd) built for 'macOS macCatalyst zippered(macOS/Catalyst)'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I've been trying to test if the StoreKit API returns finished consumables when you fetch all transactions.
I added the SKIncludeConsumableInAppPurchaseHistory key to my Info.plist
I purchased 2 consumables and verified that they show up when you fetch all transactions before I finish them.
But when I fetch all transactions after finishing them, it doesn't contain the finished consumables.
Has anyone had success with this or is this a bug?
I tested using Xcode Version 16.0 (16A242d) running a macOS Catalyst app on Sonoma 14.7 (23H124).
Edit: If I try to get the transaction history using the https://api.storekit-sandbox.itunes.apple.com/inApps/v2/history from my server, I get the transactions back. So it seems like it's a bug on the client side.
I need to bring an iOS application to macOS using Catalyst. This application contain parts where it waits for a button to be pressed in the main thread, using
[[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
in a while loop to allow some dispatching while waiting. I know that this is not good style, but I need to convert this old source code and mentioned that when using this part of code under Catalyst, the main thread will not dispatch. So the button cannot be clicked, and a beach ball appears after two seconds.
I saw a similar construct for native macOS applications:
NSEvent *event= [[NSApplication sharedApplication] nextEventMatchingMask:NSEventMaskAny untilDate:[NSDate dateWithTimeIntervalSinceNow:0.1] inMode:NSDefaultRunLoopMode dequeue:YES];
if (event) {
[[NSApplication sharedApplication] sendEvent:event]; }
but I do not have access to NSEvent and NSApplication in a Catalyst environment.
Question: I there any code snippet which I can use to achieve the above? I do not want to completely rewrite old code if there is a solution for this. Any ideas or hints are highly appreciated.
Thank you!
Markus