Mac Catalyst

RSS for tag

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

Mac Catalyst Documentation

Posts under Mac Catalyst tag

112 Posts
Sort by:
Post marked as solved
4 Replies
586 Views
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?
Posted
by
Post not yet marked as solved
1 Replies
383 Views
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.
Posted
by
Post not yet marked as solved
0 Replies
446 Views
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!
Posted
by
Post not yet marked as solved
0 Replies
559 Views
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") } }
Posted
by
Post not yet marked as solved
1 Replies
572 Views
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.
Posted
by
Post not yet marked as solved
2 Replies
582 Views
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?
Posted
by
Post not yet marked as solved
0 Replies
391 Views
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
Posted
by
Post not yet marked as solved
4 Replies
522 Views
I have a WKWebView that sets the UIDelegate: self.webView.UIDelegate = self; The following methods are never called when I right click in the WKWebView to being up a context menu: -(void)webView:(WKWebView*)webView contextMenuForElement:(WKContextMenuElementInfo*)elementInfo willCommitWithAnimator:(id <UIContextMenuInteractionCommitAnimating>)animator -(void)webView:(WKWebView*)webView contextMenuConfigurationForElement:(WKContextMenuElementInfo*)elementInfo completionHandler:(void (^)(UIContextMenuConfiguration * _Nullable configuration))completionHandler - (void)webView:(WKWebView *)webView contextMenuDidEndForElement:(WKContextMenuElementInfo *)elementInfo; This is from a Mac Catalyst app (I'm on macOS 14.0 23A344)
Post not yet marked as solved
0 Replies
373 Views
I have a Mac Catalyst app configured like so: The root view controller on the window is a tripe split UISplitViewController. The secondary view controller in the Split View controller is a view controller that uses WKWebView. Load a website in the WKWebview that has a video. Expand the video to “Full screen” (on Mac Catalyst this is only “Full window” because the window does not enter full screen like AppKit apps do). The NSToolbar overlaps the “Full screen video.” On a triple Split View controller only the portions of the toolbar in the secondary and supplementary columns show through (the video actually covers the toolbar area in the “primary” column). The expected results: -For the video to cover the entire window including the NSToolbar. Actual results: The NSToolbar draw on top of the video. -- Anyone know of a workaround? I filed FB13229032
Post not yet marked as solved
1 Replies
396 Views
I'm using WKWebView in a Mac Catalyst app (not sure if using Catalyst makes a difference but it seems WKWebView doesn't get the "full" Mac version AppKit apps do so maybe it does). When a website has a video playing and if I click the button that I guess is a Picture in Picture button next to the "close" button the web kit process gets an unrecognized selector sent to instance exception. -[WebAVPlayerLayer startRedirectingVideoToLayer:forMode: <-- Unrecognized selector. In debugging mode at least my app doesn't crash the video continues to play and the WKWebview is unresponsive to user interaction. I have to force quit my app. -- I'm on Sonoma 14.0
Post not yet marked as solved
1 Replies
376 Views
I have a customizable NSToolbar (using in a Mac Catalyst app "optimized for Mac"). When I right click and choose "Customize toolbar" I get the following error: Conflicting constraints detected: ( "<NSLayoutConstraint:0x6000014a24e0 NSToolbarItemGroupView:0x13de568c0.width <= 88.5 (active)>", "<NSAutoresizingMaskLayoutConstraint:0x6000014f5f90 h=--& v=--& NSToolbarItemGroupView:0x13de568c0.width == 89 (active)>" ). Will attempt to recover by breaking <NSLayoutConstraint:0x6000014a24e0 NSToolbarItemGroupView:0x13de568c0.width <= 88.5 (active)>. Unable to simultaneously satisfy constraints: ( "<NSLayoutConstraint:0x6000014a24e0 NSToolbarItemGroupView:0x13de568c0.width <= 88.5 (active)>", "<NSAutoresizingMaskLayoutConstraint:0x6000014f5f90 h=--& v=--& NSToolbarItemGroupView:0x13de568c0.width == 89 (active)>" ) Will attempt to recover by breaking constraint <NSLayoutConstraint:0x6000014a24e0 NSToolbarItemGroupView:0x13de568c0.width <= 88.5 (active)> Set the NSUserDefault >NSConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints to YES to have ->[NSWindow visualizeConstraints:] automatically called when this happens. And/or, set a symbolic breakpoint on LAYOUT_CONSTRAINTS_NOT_SATISFIABLE to catch this in the debugger.
Post not yet marked as solved
1 Replies
1.1k Views
Okay so I'm getting this log every time I present a UIAlertController: Mac Catalyst: Presenting view controller <UIAlertController: 0x10f027000> from detached view controller <MyViewController: 0x10d104080> is not supported, and may result in incorrect safe area insets and a corrupt root presentation. Make sure <MyViewController: 0x10d104080> is in the view controller hierarchy before presenting from it. Will become a hard exception in a future release. A few points: MyViewController is not detached and the presentation shows just fine. I specifically check for this before presenting the alert controller like so: BOOL okayToPresentError = (self.isViewLoaded && self.view.window != nil); if (okayToPresentError) { [self presentErrorInAlertController:error]; } else { //Wait until view did appear. self.errorToPresentInViewDidAppear = error; } It spews out every time an error is fed back to my app and I present the alert controller (I can turn off the network connection and I show an alert controller with a "retry" button in it which will loop the error back so I can replay the error alert presentation over and over again) . Every time the alert controller is presented, I get this spewing in the console. Please don't start throwing hard exceptions because the check is faulty.
Post not yet marked as solved
1 Replies
388 Views
I have a UIViewController subclass I'm using in Mac Catalyst. This view controller is only ever presented as a sheet. When I try to make a live preview for it the preview is displayed a gigantic size (not the sheet's actual size at runtime). I made a separate thread about this: https://developer.apple.com/forums/thread/738641 In order to be able to preview the view controller for Mac Catalyst at the desired size I figured I'd present it on another view controller. #Preview { let wrapperVC = WrapperViewController() return wrapperVC } //In WrapperViewController override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) if (firstViewDidAppear) { firstViewDidAppear = false view.backgroundColor = UIColor.yellow let realVC = ActualVCIWantToPreview() realVC.modalPresentationStyle = .formSheet present(realVC, animated: false); } } But that's not working. However if I change the device from Mac to iPad it does work so it appears modal presentations aren't working for Live Previews on Mac Catalyst (unless I'm doing something wrong but Xcode is reporting no errors it just isn't showing my presented view controller).
Post not yet marked as solved
0 Replies
284 Views
I have a Mac Catalyst app. When using "Live Previews" in Xcode 15 for a view controller of mine the live preview renders at a gigantic size in the Preview. This view controller is only ever presented as a "sheet" on Mac at a fixed size so ideally I'd like to be able to specify the "window size" for the preview environment. Is there a way to do this? Thanks in advance.
Post marked as solved
6 Replies
1.5k Views
I get the following message when I try to run this app in Xcode. Could not launch AppName. Runningboard has returned error 5. Please check the system logs for the underlying cause of the error. Interestingly, the destination Mac (Mac Catalyst) destination does launch. The funny thing is there is a companion app almost exactly like this one that launches fine. Any help with this would be greatly appreciated. Xcode helped me to file a feedback. The number is FB13206919.
Posted
by
Post not yet marked as solved
0 Replies
351 Views
Hello, I'm trying to build my app for macOS using Mac Catalyst. However, I've encountered an issue while trying to create an archive build for Mac Catalyst using Xcode command line tools. I've set up a new profile specifically for Mac Catalyst and I'm using the Apple Distribution Profile. However, when I attempt to export using this profile, I encounter the following error: "error: exportArchive: No signing certificate 'Mac Installer Distribution' found." I've also tried using a macOS profile, but it results in an error indicating that the profile used is not a Mac Catalyst profile. Upon investigating my Apple Developer Account, I've noticed that when I select macOS, I can see the Mac Distribution option. However, when I choose Mac Catalyst, I only see the Apple Distribution option in the certificate selection. Could you please advise on the correct steps to create a profile and certificate for a Mac Catalyst build? Here's the export info plist and the command I'm using to export the Mac Catalyst app: CLI xcrun xcodebuild -exportArchive -archivePath "${ARCHIVE_PATH}" -exportOptionsPlist "Path/MacOS_AppStore.plist" -exportPath "${DEPLOY_DIR}" Export Options Plist:
Posted
by
Post not yet marked as solved
0 Replies
238 Views
Hello, I'm currently working on an unreleased iOS app with support for macOS using Mac Catalyst. However, I've encountered an issue while trying to create an archive build for Mac Catalyst using Xcode command line tools. I've set up a new profile specifically for Mac Catalyst and I'm using the Apple Distribution Profile. However, when I attempt to export using this profile, I encounter the following error: "error: exportArchive: No signing certificate 'Mac Installer Distribution' found." I've also tried using a macOS profile, but it results in an error indicating that the profile used is not a Mac Catalyst profile. Upon investigating my Apple Developer Account, I've noticed that when I select macOS, I can see the Mac Distribution option. However, when I choose Mac Catalyst, I only see the Apple Distribution option in the certificate selection. Could you please advise on the correct steps to create a profile and certificate for a Mac Catalyst build? Here's the export info plist and the command I'm using to export the Mac Catalyst app: xcrun xcodebuild -exportArchive \ -archivePath "${ARCHIVE_PATH}" \ -exportOptionsPlist "Path/MacOS_AppStore.plist" \ -exportPath "${DEPLOY_DIR}" Export Options Plist: <dict> <key>method</key> <string>app-store</string> <key>signingStyle</key> <string>manual</string> <key>teamID</key> <string>G28C52EEHV</string> <key>uploadBitcode</key> <true/> <key>uploadSymbols</key> <true/> <key>signingCertificate</key> <string>Apple Distribution</string> <key>provisioningProfiles</key> <dict> <key>com.company.projectName</key> <string>projectName_MacCat_AppStore</string> </dict> </dict> I appreciate any guidance on this matter.
Posted
by
Post not yet marked as solved
0 Replies
489 Views
When using xcodebuild to build my project, I specify a destination of generic/platform=macOS Xcode informs me that my destination is ambiguous as there is a generic destination for Mac Catalyst. --- xcodebuild: WARNING: Using the first of multiple matching destinations: { platform:macOS, name:Any Mac } { platform:macOS, variant:Mac Catalyst, name:Any Mac } At the end of the day, that's OK. It's selected the proper destination by happenstance. But is there a way t change my destination specifier so that it can zero in on the MacOS destination that is not the MacCatalyst variant? I've tried using "generic/platform=macOS,variant=". But that does not work.
Posted
by
Post not yet marked as solved
2 Replies
473 Views
When I build my app for my real device I get this error /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.4.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSURL.h:10:9 'Foundation/NSURLHandle.h' file not found I have latest macOS (13.5.2 (22G91)) and the latest Xcode (14.3.1 (14E300c)). I got this issue about 5 months now, even on my old Intel mac. My new M1 mac was not restored by a Backup and I still get this issue. Can someone please give me a hint or advice to get this issue fixed?
Posted
by