Mac Catalyst

RSS for tag

Start building a native Mac app from your current iPad app using Mac Catalyst.

Posts under Mac Catalyst tag

111 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

Catalyst - running macOS exec file using Process returns error
Running a Process executableURL path for a Catalyst target using a macOS type bundle returns the following error as output: (/Applications/Xcode-15.1.0.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Debugger/libViewDebuggerSupport_macCatalyst.dylib), but incompatible platform (have \'MacCatalyst\', need \'macOS\')) Is it possible to set which dylib platform is used by the macOS bundle executable file instead of using the MacCatalyst one?
0
1
504
Jan ’24
Issue with SwiftUI Alert Freezing in AUv3 Extension Project on Mac Catalyst
Hello, I am working on an AUv3 extension project using SwiftUI in Xcode and have encountered a peculiar issue when implementing a simple alert on Mac Catalyst. The code is straightforward; it's merely an alert triggered by a button within a SwiftUI view. Here's the relevant portion of the code: import SwiftUI struct SwiftAUv3ExtensionMainView: View { var parameterTree: ObservableAUParameterGroup @State var showingAlert = false var body: some View { VStack { ParameterSlider(param: parameterTree.global.gain) Button(action: {showingAlert = true}, label: { Text("Button") }) } .alert("Alert", isPresented: $showingAlert, actions: {}, message: { Text("Message") }) } } The problem arises when this alert is displayed and subsequently closed. Upon closing the alert, the cursor turns into a spinning rainbow and the app freezes for several seconds. Additionally, Xcode's console displays the warning: -[NSWindow makeKeyWindow] called on _NSAlertPanel which returned NO from -[NSWindow canBecomeKeyWindow]. I am looking for insights or solutions to address this issue. Has anyone else experienced similar problems with SwiftUI alerts in AUv3 extension projects, especially when using Mac Catalyst? Any advice or suggestions would be greatly appreciated. Thank you.
0
0
546
Jan ’24
Crash entering Picture in Picture from webview on Mac Catalyst or Made for iPad
Crash seems to be in a private Apple framework. There's some other reports of this floating around but no solutions so far. Any ideas? *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[WebAVPlayerLayer startRedirectingVideoToLayer:forMode:]: unrecognized selector sent to instance 0x6000037033c0' *** First throw call stack: ( 0 CoreFoundation 0x0000000187d56800 __exceptionPreprocess + 176 1 libobjc.A.dylib 0x000000018784deb4 objc_exception_throw + 60 2 CoreFoundation 0x0000000187e083bc -[NSObject(NSObject) __retain_OA] + 0 3 CoreFoundation 0x0000000187cc0a84 forwarding + 1572 4 CoreFoundation 0x0000000187cc03a0 _CF_forwarding_prep_0 + 96 5 AVKit 0x00000001bdc81f30 -[__AVPlayerLayerView startRoutingVideoToPictureInPicturePlayerLayerView] + 156 6 AVKit 0x00000001bdcf1d48 -[AVPictureInPicturePlatformAdapter(Common) _setRoutingVideoToHostedWindow:pictureInPictureViewController:source:] + 84 7 AVKit 0x00000001bdcd952c -[AVPictureInPicturePlatformAdapter startPictureInPicture] + 380 8 AVKit 0x000000022883000c -[AVPictureInPicturePlatformAdapterAccessibility startPictureInPicture] + 44 9 AVKit 0x00000001bdcddea0 -[AVPictureInPictureController startPictureInPicture] + 216 10 WebCore 0x00000001c75277c8 -[WebAVPlayerViewController startPictureInPicture] + 128 11 libdispatch.dylib 0x0000000102c64f14 _dispatch_call_block_and_release + 32
2
0
577
Dec ’23
How to prevent scene restoration in a catalyst app
Hello all, I'm porting my existing app to catalyst with optimized for mac option. However, I noticed the app will sometimes restore previous open windows if I previously kill it in Xcode. However, these restored windows are also just showing the app entry content instead of restoring the previous scene content. Question, is there anyway to disable this restore scene behavior? Thanks!
1
0
443
Dec ’23
How do I open my app's section of Notification settings in Catalyst?
I have a button in my iOS app that opens the Settings app to my app's Notification permissions section. I use UIApplicationOpenSettingsURLString for this (or UIApplicationOpenNotificationSettingsURLString on iOS 15.4 and later). On Catalyst, both of these simply open the settings screen that is auto-generated from the Settings bundle. How do I get it to open to the appropriate place in System Settings?
1
1
497
Dec ’23
Share submenu in Mac Catalyst and UICommandTagShare
With Mac Catalyst, in Big Sur and Monterey, you could use UICommandTagShare as the property list for a UICommand in combination with activityItemsConfiguration and itemProvidersForActivityItemsConfiguration to allow a "Share" submenu to appear in a menu in your app (for instance, under the File menu like many other apps). Starting in Ventura, this submenu no longer appears with that same code, and instead the UICommandTagShare command in the menu now just displays "Share" with no submenu, which triggers a UIActivityViewController to appear in the main window. Is there any way to still allow a Share submenu to work in Ventura and beyond with Mac Catalyst? Thanks so much for any help!
1
1
402
2w
SFSafariViewController behaves differently in MacCatalyst than iOS
I was loading a URL using SFSafariViewController in my app and also implemented the SFSafariViewControllerDelegate. I noticed that when I am running my app on iOS, I am not getting the callBack in safariViewControllerDidFinish(_:) until or unless "Done" button is pressed. But when I am running it on MacCatalyst following behaviour is noticed: default browser is launched. I get a callback in safariViewControllerDidFinish(_:) without any of my action(like pressing "Done" button). Is this the expected behaviour? I am curious to know why I am getting callback in safariViewControllerDidFinish(_:).
1
0
500
Jan ’24
List reordering doesn't work in a popover on Sonoma
List items do not appear to be moveable when they are contained within a popover on Mac Catalyst running on macOS Sonoma. Dragging and dropping a list item simply returns it to its original location, and onMove(preform:) is not called. The same happens using the drag handles with an EditButton() or .environment(\.editMode, .constant(.active)). Below is a reproducible sample which, to my knowledge, worked as expected on Ventura. It also currently works as expected on iPad. Changing the popover to a sheet makes it work on Mac Catalyst, but then, the view takes up a lot of unnecessary space. Does anyone have any good workarounds for this issue? struct ContentView: View { @State private var isShowingPopover = false @State private var items = ["one", "two", "three"] var body: some View { Button("Show Popover") { isShowingPopover = true } .popover(isPresented: $isShowingPopover) { List { ForEach(items, id: \.self) { item in Text(item) } .onMove { fromOffsets, toOffset in items.move(fromOffsets: fromOffsets, toOffset: toOffset) } } .frame(minWidth: 300, minHeight: 270) } } }
1
1
459
Dec ’23
Use prebuilt dylib built for macOS in macCatalyst?
Is there a way to link a prebuilt dylib that was built for the 'macOS' platform on Mac Catalyst without being warned by Xcode? Generally it would be better to just recompile for Mac Catalyst but this is a third party library and they have a complicated build system with dozens of dependencies that doesn't support Mac Catalyst as of now (although they have iOS and Mac 'regular'). So I would have to spend quite a bit of time trying to sort through their build system to make a Catalyst version myself. The library uses no platform specific UI code and I'm fairly certain that macOS build would work just fine on Mac Catalyst without any changes since it isn't UI related at all. It seems to work fine (apart from Xcode warning me about linking a .dylib built for macOS on Mac Catalyst). I could shim all this away in a NSBundle that is aware of the AppKit world but then I have to make all method calls to the third party framework on Mac Catalyst through the bundle and it would separate my iOS and Catalyst code relying on the same implementation which isn't great. Is there a way I could just replace the 'macOS' platform in the .dylib with macCatalyst to get rid of the warning?
2
0
910
Nov ’23
Render Menu Items with Icon (e.g SFSymbol) on Catalyst
Hello, is there a recommended way to render Menu items, e.g in a SwiftUI ContextMenu with icon (SFSymbols)? Let's say I have the following setup: Both buttons render fine on native macOS (e.g Sonoma) but Catalyst refuses to render the symbol at all. I tried every possible combination I could think off. The only way I found was to directly copy and paste a symbol from the SF symbols app and inline it with the label string as unicode. Unfortunately I have a couple custom SF symbols so this isn't really an option for me. I feel like this is a perfectly valid usecase, as it makes the menu visually a lot easier scannable. With UIKit and Ventura this at least worked for Menubar items but now also seems broken on Sonoma. I would greatly appreciate any hints. Thanks!
2
0
764
Nov ’23
Why does text selection not work in MacCatalyst app's WKWebView on macOS Sonoma Only
Can not select anything within WkWebView editor view of my MacCatalyst app when running on macOS 14 Sonoma. Any selection gesture or command key fails to select anything in content editable WKWebView, so none of the Editor tools can be activated. My application uses the nnhubbard / ZSSRichTextEditor WKWebView-based Rich Text Editor: https://github.com/nnhubbard/ZSSRichTextEditor. The app is built with Xcode 15.0 or 15.0.1. The app is a Catalyst app that implements an editor view with a ZSSRichTextEditor WKWebView. The problem does not occur if the the app is run in iOS or macOS 11, 12, or 13 (Catalina, Monterey, or Ventura.) The issue only occurs in macOS 14 Sonoma.
2
1
608
Nov ’23
MenuBarExtra for Mac Catalyst App
I have a Mac Catalyst App that I switched over to the SwiftUI lifecycle. I am trying to add MenuBarExtra to the app : if #available(macOS 13.0, *) { MenuBarExtra("....", systemImage: ......) { .......... } } However, I get an error : 'init(_:systemImage:content:)' is unavailable in iOS 'MenuBarExtra' is unavailable in iOS How do I add MenuBarExtra to the app?
4
0
692
Nov ’23
Cannot reorder rows in UITableView under Mac Catalyst
It appears that we are not able to reorder rows in our tables when running our iOS/iPadOS app under Mac Catalyst. It appears that all the delegate methods are returning true indicating the row can be moved and edited. The reordering handles appear in editing move and the row can be moved around (also using drag and drop) but the user interface is not indicating that the row can be dropped to be reordered. It's as if the proposed destination path is being rejected. I tried setting up that delegate method (thinking that maybe the default for that is messed up on Mac Catalyst) but it had no effect. Every table in our system performs this way. Here is a link to an example video that shows the table view not working: https://onsongapp.s3.amazonaws.com/Reordering%20Example.mp4 Please advise if there is something else that needs to be implemented or changed for Mac Catalyst to properly handle table cell reordering.
2
1
461
Nov ’23
Swift Package Plugin Context Tool Path is bugged when building for Mac Catalyst
I have a Swift Package Build Tool Plugin to generate localizations and design tokens, which looks like this currently. // Copyright © 2023 MEGA Limited. All rights reserved. import PackagePlugin @main struct GenerateTokenBuildTool: BuildToolPlugin { func createBuildCommands(context: PluginContext, target: Target) async throws -> [Command] { guard let target = target as? SourceModuleTarget else { return [] } return try target.sourceFiles(withSuffix: "xcassets").map { assetCatalog in let base = assetCatalog.path.stem let input = assetCatalog.path let output = context.pluginWorkDirectory.appending(["\(base).swift"]) // Use this when archiving for MacCatalyst let tool = try context.tool(named: "AssetTokenGenerator").path let toolName = tool.lastComponent let path = tool.removingLastComponent() let macPath = path.removingLastComponent().appending(subpath: path.lastComponent + "-maccatalyst") let executable = macPath.appending(subpath: toolName) // // Use this when archiving for iOS/iPadOS // let executable = try context.tool(named: "AssetTokenGenerator").path return .buildCommand( displayName: "Generating tokens for \(base).xcassets", executable: executable, arguments: [input.string, output.string], inputFiles: [input], outputFiles: [output] ) } } } If you notice, I need to do a bit of manual bug fixing when determining the path of my executable. When building for Mac Catalyst, context.tool(named:).path is pointing to an incorrect folder, thus failing the build for my project with this error: Command PhaseScriptExecution failed with a nonzero exit code sandbox-exec: execvp() of '//Users/mega-jfe/Library/Developer/Xcode/DerivedData/MEGAVPN-efdcwfcaosxfvneqjuvhrvdmbkax/Build/Products/Debug/AssetTokenGenerator' failed: No such file or directory It's suppposed to be using the Debug-maccatalyst folder, but Xcode is pointing the path to Debug. I feel like this is a bug, or else please let me know how I can handle this so that I can build for both without manually changing the code when building for Catalyst. Thanks!
0
0
502
Oct ’23
How do I work around a Mac Catalyst framework bug where no Core Animation output is shown in an export session?
This is verified to be a framework bug (occurs on Mac Catalyst but not iOS or iPadOS), and it seems the culprit is AVVideoCompositionCoreAnimationTool? /// Exports a video with the target animating. func exportVideo() { let destinationURL = createExportFileURL(from: Date()) guard let videoURL = Bundle.main.url(forResource: "black_video", withExtension: "mp4") else { delegate?.exporterDidFailExporting(exporter: self) print("Can't find video") return } // Initialize the video asset let asset = AVURLAsset(url: videoURL, options: [AVURLAssetPreferPreciseDurationAndTimingKey: true]) guard let assetVideoTrack: AVAssetTrack = asset.tracks(withMediaType: AVMediaType.video).first, let assetAudioTrack: AVAssetTrack = asset.tracks(withMediaType: AVMediaType.audio).first else { return } let composition = AVMutableComposition() guard let videoCompTrack = composition.addMutableTrack(withMediaType: AVMediaType.video, preferredTrackID: Int32(kCMPersistentTrackID_Invalid)), let audioCompTrack = composition.addMutableTrack(withMediaType: AVMediaType.audio, preferredTrackID: Int32(kCMPersistentTrackID_Invalid)) else { return } videoCompTrack.preferredTransform = assetVideoTrack.preferredTransform // Get the duration let videoDuration = asset.duration.seconds // Get the video rect let videoSize = assetVideoTrack.naturalSize.applying(assetVideoTrack.preferredTransform) let videoRect = CGRect(origin: .zero, size: videoSize) // Initialize the target layers and animations animationLayers = TargetView.initTargetViewAndAnimations(atPoint: CGPoint(x: videoRect.midX, y: videoRect.midY), atSecondsIntoVideo: 2, videoRect: videoRect) // Set the playback speed let duration = CMTime(seconds: videoDuration, preferredTimescale: CMTimeScale(600)) let appliedRange = CMTimeRange(start: .zero, end: duration) videoCompTrack.scaleTimeRange(appliedRange, toDuration: duration) audioCompTrack.scaleTimeRange(appliedRange, toDuration: duration) // Create the video layer. let videolayer = CALayer() videolayer.frame = CGRect(origin: .zero, size: videoSize) // Create the parent layer. let parentlayer = CALayer() parentlayer.frame = CGRect(origin: .zero, size: videoSize) parentlayer.addSublayer(videolayer) let times = timesForEvent(startTime: 0.1, endTime: duration.seconds - 0.01) let timeRangeForCurrentSlice = times.timeRange // Insert the relevant video track segment do { try videoCompTrack.insertTimeRange(timeRangeForCurrentSlice, of: assetVideoTrack, at: .zero) try audioCompTrack.insertTimeRange(timeRangeForCurrentSlice, of: assetAudioTrack, at: .zero) } catch let compError { print("TrimVideo: error during composition: \(compError)") delegate?.exporterDidFailExporting(exporter: self) return } // Add all the non-nil animation layers to be exported. for layer in animationLayers.compactMap({ $0 }) { parentlayer.addSublayer(layer) } // Configure the layer composition. let layerComposition = AVMutableVideoComposition() layerComposition.frameDuration = CMTimeMake(value: 1, timescale: 30) layerComposition.renderSize = videoSize layerComposition.animationTool = AVVideoCompositionCoreAnimationTool( postProcessingAsVideoLayer: videolayer, in: parentlayer) let instructions = initVideoCompositionInstructions( videoCompositionTrack: videoCompTrack, assetVideoTrack: assetVideoTrack) layerComposition.instructions = instructions // Creates the export session and exports the video asynchronously. guard let exportSession = initExportSession( composition: composition, destinationURL: destinationURL, layerComposition: layerComposition) else { delegate?.exporterDidFailExporting(exporter: self) return } // Execute the exporting exportSession.exportAsynchronously(completionHandler: { if let error = exportSession.error { print("Export error: \(error), \(error.localizedDescription)") } self.delegate?.exporterDidFinishExporting(exporter: self, with: destinationURL) }) } Not sure how to implement a custom compositor that performs the same animations as this reproducible case: class AnimationCreator: NSObject { // MARK: - Target Animations /// Creates the target animations. static func addAnimationsToTargetView(_ targetView: TargetView, startTime: Double) { // Add the appearance animation AnimationCreator.addAppearanceAnimation(on: targetView, defaultBeginTime: AVCoreAnimationBeginTimeAtZero, startTime: startTime) // Add the pulse animation. AnimationCreator.addTargetPulseAnimation(on: targetView, defaultBeginTime: AVCoreAnimationBeginTimeAtZero, startTime: startTime) } /// Adds the appearance animation to the target private static func addAppearanceAnimation(on targetView: TargetView, defaultBeginTime: Double = 0, startTime: Double = 0) { // Starts the target transparent and then turns it opaque at the specified time targetView.targetImageView.layer.opacity = 0 let appear = CABasicAnimation(keyPath: "opacity") appear.duration = .greatestFiniteMagnitude // stay on screen forever appear.fromValue = 1.0 // Opaque appear.toValue = 1.0 // Opaque appear.beginTime = defaultBeginTime + startTime targetView.targetImageView.layer.add(appear, forKey: "appear") } /// Adds a pulsing animation to the target. private static func addTargetPulseAnimation(on targetView: TargetView, defaultBeginTime: Double = 0, startTime: Double = 0) { let targetPulse = CABasicAnimation(keyPath: "transform.scale") targetPulse.fromValue = 1 // Regular size targetPulse.toValue = 1.1 // Slightly larger size targetPulse.duration = 0.4 targetPulse.beginTime = defaultBeginTime + startTime targetPulse.autoreverses = true targetPulse.repeatCount = .greatestFiniteMagnitude targetView.targetImageView.layer.add(targetPulse, forKey: "pulse_animation") } }
1
0
673
Oct ’23
Strange vertical alignment in Catalyst navigation bar titles in modal sheets w/Catalyst & macOS Sonoma
Is anyone else running into an issue with navigation bar titles in Catalyst app being shown higher up than normal when presented as a modal sheet under Sonoma (see screenshot)? I tried adjusting the titlePositionAdjustment for the appearance, but this only affects the title and not any buttons that may be in the navigation bar, making them uneven. Any suggestions would be helpful as I'm at my wits end on this one.
2
0
725
Nov ’23
UIAlertController no longer appears as a popover in macOS Sonoma
Prior to macOS 14, a Catalyst app could present a UIAlertController as a popover, just as you can on the iPad. While this still works on the iPad, the presentation on macOS now uses the same style as the iPhone. The UIAlertController's popoverPresentationController property is always nil, no matter how it is configured. Doe anyone know of a way to restore the prior behavior under Sonoma?
3
2
751
Jun ’24
Navigation bar not shown in Supplementary view of a UISplitView in macOS Sonoma
I've run into a problem that has been giving me fits for a while and have yet to be able to find a solution. We have a Catalyst app that uses a three-pane UISplitView. The middle and third panes show the navigation bar of the UINavigationController hosted in each pane. However, when building under Xcode 15, the navigation bar is not shown in the middle pane when running under macOS 14. It is shown, as expected, when the app is run under prior versions of macOS. It also appears as it should under macOS 14 if the app is built with Xcode 14. If you push another view controller onto the navigation controller's stack with the animate flag set to true, the navigation bar will appear. When you go back to the root controller, the navigation bar is present as it should be. However, if you push the controller with the animate flag set to false, the navigation bar does not appear. I've been able to reproduce this in an isolated test app with just the relevant components. The first screenshot at the end is from a test app that illustrates the problem. The second screenshot shows what it should look like (and does look like under macOS 13). It should be noted that UINavigationBar.appearance().preferredBehavioralStyle = .pad is set. If any Apple folk would kindly like to look into this, I created a feedback for it: FB13260893. The feedback entry has a sample app, screenshots, and even a screen recording demonstrating the problem. Has anyone else run into this or does anyone have any suggestions for a fix/workaround? Thanks, Kevin
2
1
524
Jun ’24