Post

Replies

Boosts

Views

Activity

Reply to Action Extension Won't Launch Outside Mac App Store: Prompting policy for hardened runtime; service: kTCCServiceAppleEvents requires entitlement com.apple.security.automation.apple-events but it is missing
Appears to have been some sort of code signing issue. No useful errors from Xcode. The action extension would show up in the list and just wouldn't work when you tried to use it. So I tried toggling various code signing settings ...from automatic to manual etc and back again. For whatever reason when I set code signing back to automatic Xcode didn't complain but the extension didn't work. Would be great if the code signing issues were caught at compile time and displayed instead of letting me sign and notarize a nonworking extension. I ended up just deleting the entire Action Extension target and making a new one, adding all the same compile sources and it works. Butt... NSTextView shows action extensions via the rollover button but the menu items are disabled (FB17449863)! Seems action extension with NSExtensionActivationSupportsText set to yes only work in Safari.... any workarounds to that?
Topic: UI Frameworks SubTopic: AppKit Tags:
May ’25
Reply to App Groups on macOS, 'Register App Groups' Code Signing Problems
In this app I have shared preferences for the main app, an Action Extension, a Helper app, and an XPC service. I do have another app that has an XPC service that writes files inside the group container. When the XPC service is done the main app accesses the files. From App Groups: macOS vs iOS: Working Towards Harmony. On 21 Feb 2025 we rolled out a change to the Developer website that completes the support for iOS-style app group IDs on the Mac. Specifically, it’s now possible to create a Mac provisioning profile that authorises the use of an iOS-style app group ID. I'm sure there is a reason but I wonder why existing group container ids can't be registered and why making a new group with a "group." prefix is required.
Topic: Code Signing SubTopic: Entitlements Tags:
May ’25
Reply to Is applicationDidFinishLaunching: guaranteed to be called before INIntent delegate methods when app is launched via a Shortcut?
I ended up refactoring my code so I can handle the possibility of performing the intent action before the main window controller is loaded even if it isn't possible (I wouldn't want to instantiate it in the intent handler action because I don't want to interfere with certain logic in app launch). Probably should have designed it this way from the beginning anyway, the action doesn't need to be tied to the window controller. Still would like to know about app lifecycle here out of curiosity
Topic: UI Frameworks SubTopic: AppKit Tags:
May ’25
Reply to Does INIntent no longer work on macOS? Can't get shortcut to show up in Shortcuts app
So I got one to show up..not sure how. I temporarily added a parameter (but my shortcut shouldn't take any parameters). I also tried adding it via: [[INVoiceShortcutCenter sharedCenter] setShortcutSuggestions:@[shortCut1]]; So I'm not sure if adding the parameter or using -setShortcutSuggestions: did it. Now I removed the parameter in the .intentdefinition. AND I cleared INVoiceShortcutCenter like so: [[INVoiceShortcutCenter sharedCenter] setShortcutSuggestions:@[]]; // empty array And rebuilt the app. And now I'm having the problem in reverse (it remains in Shortcuts app list and I can't get it to be removed). Also added a second shortcut (I need two)...and the first one stubbornly won't go away and the second one won't show up....
May ’25
Reply to App Group, Shared User Defaults, Finder Sync Extension Not getting user defaults.
Meh. Somehow I must've done something (or there is some Xcode bug) but I got Xcode to generate another .entitlement file for the extension without realizing it.....it was called something like: MyEntitlement.release.entitlements....and it was set to Release mode. The group container ID was only getting added to the release mode entitlement file, not the .entitlement file being used in debug mode. Fixed that.
Topic: UI Frameworks SubTopic: AppKit Tags:
May ’25
Reply to MPRemoteCommandCenter not updating play/pause button to proper state on iOS
So instead of deactivating the audio session in my pause method I just leave it active and wait this: // Listen for UIApplicationWillResignActiveNotification -(void)appWillResignActive:(NSNotification*)notification { // player node paused? if (self.amIPaused) // { // Then we must audio engine pause. [self.audioEngine pause]; // Then we must deactivate the audio session. [self runOperationToDeactivateAudioSession]; } }
Topic: Media Technologies SubTopic: Audio Tags:
Feb ’25
Reply to MPRemoteCommandCenter not updating play/pause button to proper state on iOS
So I think the playback time issue (audio being skipped) when I pause both the playerNode and the audio engine is that when resuming the playback...I call a helper method that does something like this: -(void)resume { if (!self.playerNode.isPlaying) { [self _startAudioEngineIfNotRunningAndConnectPlayerNodeToMainMixer]; } else { // Already playing. } } Which has a check like -(BOOL)_startAudioEngineIfNotRunningAndConnectPlayerNodeToMainMixer if (!self.audioEngine.isRunning) { // connect the player node to the main mixer node and start the engine.. //code here... } else { // engine already running... return YES; } If I modify the _startAudioEngineIfNotRunningAndConnectPlayerNodeToMainMixer to include this check: NSArray<AVAudioConnectionPoint *> *connections = [engine outputConnectionPointsForNode:playerNode outputBus:0]; if (connections.count > 0) { // player node already connected... only need to start the engine } else{ // connect the player node... } Playback position isn't lost on resume. So that's good. When I deactivated the audio session and got that AVAudioSessionErrorCodeIsBusy error perhaps the system paused the audio session and returned that error to tell me about my "incorrect API use." In regards to my initial issue regarding the MPRemoteCommandCenter I think what I'm going to do is this: Only pause the player node in my -pause method and keep the audio session running if my app is in the foreground. When/if my app is moved to the background if my player node is paused I'll pause the audio engine as well and deactivate the audio session for the sake of getting the 'now playing center' to update the toggle play-pause button image. Since this is async and in a background task I have to hope it runs and updates the now playing center button before the user can see it I'm still thinking about this: I don't think this is currently possible...but I'm not sure if there is ever a situation where my app can be on screen at the same time as the "Now Playing Center" in a multi-window situation. If so the play-pause toggle button will have the wrong image until my app is backgrounded. So there is that, if that's even possible but I don't think I have any other options? -- Perhaps my thinking is naive but I think this could be a lot easier if the system just read the MPNowPlayingInfoCenter.playbackState property on iOS instead of inferring it from AVAudioSession. If I don't own the now playing center who cares what I set the .playbackState property to? Feels like the system is in a better position to make a decision of whether or not my audio session should be deactivated than I am. But I have to explicitly deactivate my audio session when my app is backgrounded every time (if my audio is paused).
Topic: Media Technologies SubTopic: Audio Tags:
Feb ’25
Reply to MPRemoteCommandCenter not updating play/pause button to proper state on iOS
I tried pausing the player node and the audio engine: -(void)pause { [self.playerNode pause]; [self.audioEngine pause]; [self runOperationToDeactivateAudioSession]; // This does nothing on iOS: MPNowPlayingInfoCenter *nowPlayingCenter = [MPNowPlayingInfoCenter defaultCenter]; nowPlayingCenter.playbackState = MPNowPlayingPlaybackStatePaused; } The good news? My AVAudioSession -setActive:error: call to deactivate the session no longer gives me a AVAudioSessionErrorCodeIsBusy error. The bad news? When resuming playback, it doesn't play any audio still. The rest of the buffer at the time of the call to -pause is just skipped. No errors reported
Topic: Media Technologies SubTopic: Audio Tags:
Feb ’25
Reply to MPRemoteCommandCenter not updating play/pause button to proper state on iOS
After fiddling with this some more I noticed that -When I deactivate the audio session after pausing the player node (and get AVAudioSessionErrorCodeIsBusy but the play/pause button in the 'now playing center' does update its image properly)...this has a bad consequence when I resume audio. When I resume the player node I don't hear any playback. My code looks something like this: -(void)resume { [self runOperationToActivateAudioSession]; [self.playerNode play]; } So after the calls -pause (which gives AVAudioSessionErrorCodeIsBusy) and then -resume... when resuming the player node just skips to the end of the buffer instead of resuming playback (I don't hear any audio). Now if I go back to the pause method and comment out the method call to deactivate the audio session resuming playback works as expected. So it seems deactivating the audio session on pause has this side effect on resume. But if I don't deactivate the session the 'Now Playing' center shows the wrong image for the play/pause button.
Topic: Media Technologies SubTopic: Audio Tags:
Feb ’25
Reply to Populating Now Playing with Objective-C
Never used MPNowPlayingSession (I set up info/remote command center directly) but... Maybe try setting .automaticallyPublishesNowPlayingInfo = YES; and try not setting up nowPlayingInfoCenter at all...to tell the session to get metadata from AVPlayer. If that's not what you want or doesn't work.... Try using: MPNowPlayingInfoCenter *infoCenter = self.nowPlayingSession.nowPlayingInfoCenter Instead of +defaultCenter (may be the same object, but seems cleaner to do it this way). Also I think you may need to configure the MPRemoteCommandCenter. MPRemoteCommandCenter *remoteCommandCenter = self.nowPlayingSession.remoteCommandCenter; id playPauseTarget = [remoteCommandCenter.togglePlayPauseCommand addTargetWithHandler:^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent *_Nonnull event) { // implement }]; When not using a "session" and just populating the info I believe it is required you configure the remote command center as well (add play/pause etc.) to get your now playing info to show up.
Topic: Media Technologies SubTopic: Audio Tags:
Feb ’25