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()
ApplicationMusicPlayer.shared player.play() permission denied in app sandbox (Tauri)
 
 
Q