ApplicationMusicPlayer.shared player.play() permission denied in app sandbox (Tauri)

Hi,

I'm developing a Tauri V2 app on MacOS, and am wanting to implement playback controls. It seems that Apple locks down playback, requiring a signed application.

My app also has capabilities to "get currently playing track", and I confirmed this works; Apple produces a popup triggered by my await MusicAuthorization.request() call. It returns nil, of course, because I can't get anything to play via the ApplicationMusicPlayer; only through the system's Apple Music app. I understand SystemMusicPlayer is not available on MacOS, which is fine.

I'm just a little confused as it seems pretty standard to need to test playback controls quickly without having to codesign and do some provisionprofile embedding acrobatics each time Rust re-compiles target/debug. This slows down development a lot.

I do have these entries in my Entitlements.plist:

  <key>com.apple.security.personal-information.media-library</key>
  <true/>
  <key>com.apple.developer.music-kit</key>
  <true/>
  <key>com.apple.security.app-sandbox</key>
  <true/>

In my tauri.conf.json, I have: "macOS": { "entitlements": "./Entitlements.plist", "signingIdentity": "Apple Development: <name> (<id>)" }

My application works like this: I have a temporary button click to fire off a tauri<string>invoke() command which goes to a #tauri::command, which bridges to Swift code. Again, I validated that my less-permissive "get currently playing track" works; i.e., does not get permission denied.

exact error message: [swift] playMedia error: .permissionDenied (^specifically, ".permissionDenied")

My code to trigger playback of a specific media item:

    Task {
        print("[swift] entered sema Task")
        let status: MusicAuthorization.Status = await MusicAuthorization.request()
        print("auth status: \(status)")
        
        guard status == .authorized else { sema.signal(); return }
        print("passed the status guard.")

        do {
            var request = MusicCatalogResourceRequest<Song>(matching: \.id, equalTo: MusicItemID(rawValue: songId))
            request.limit = 1
            let response = try await request.response()
            guard let song = response.items.first else { sema.signal(); return }

            let player = ApplicationMusicPlayer.shared
            player.queue = [song]
            try await player.play()
            success = true
        } catch {
            print("[swift] playMedia error: \(error)")
        }
        sema.signal()
Answered by DTS Engineer in 881966022

I can’t help you with the third-party tooling side of this. My advice is that you set up a small Xcode test project to exercise the APIs in question. If you get stuck with that, I’d be happy to help. Once you get that working, you can translate that knowledge to your third-party environment. And if you have problems with that, you can seek help via its support channel.

However, I can tell you that this is wrong:

I do have these entries in my Entitlements.plist … com.apple.developer.music-kit

MusicKit is one of the most commonly hallucinating entitlements. Indeed, I listed it, with a slightly different spelling, in Determining if an entitlement is real.

Oh, and if you were using a modern version of Xcode, it would’ve told you about this, which is another good reason to prototype this stuff in Xcode.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Accepted Answer

I can’t help you with the third-party tooling side of this. My advice is that you set up a small Xcode test project to exercise the APIs in question. If you get stuck with that, I’d be happy to help. Once you get that working, you can translate that knowledge to your third-party environment. And if you have problems with that, you can seek help via its support channel.

However, I can tell you that this is wrong:

I do have these entries in my Entitlements.plist … com.apple.developer.music-kit

MusicKit is one of the most commonly hallucinating entitlements. Indeed, I listed it, with a slightly different spelling, in Determining if an entitlement is real.

Oh, and if you were using a modern version of Xcode, it would’ve told you about this, which is another good reason to prototype this stuff in Xcode.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thank you, my apologies for the hallucinated entitlement. I read your post shortly after I posted here.

One other thing, what's the documented behavior if Apple Music is in the foreground but not playing anything, and my app attempts to do player.play()? I have experienced a queue success but playback failure on MacOS (so using ApplicationMusicPlayer), only if the user has the system's Apple Music up.

What's the documented behavior if the user has something actively playing on the system music player?

Glad to hear you’re making progress.

What's the documented behavior if the user has something actively playing on the system music player?

Sadly, I can’t help you with that. I waded into this thread because I have expertise in the entitlement side of things. Otherwise I’m a complete noob when it comes to MusicKit.

I have a couple of recommendations:

  • As I mentioned above, prototype stuff in Xcode, just to get your third-party tooling out of the mix.
  • If you continue to have problems, start a new thread, using the same subtopic and tags as their thread (well, except for Entitlements).

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

ApplicationMusicPlayer.shared player.play() permission denied in app sandbox (Tauri)
 
 
Q