SystemMusicPlayer.shared.isPreparedToPlay throws

Hi there, I am seeing an error when attempting to prepareToPlay on iOS 15 Beta 5. I'm using SystemMusicPlayer's new .queue property directly as setQueue was deprecated. Are there other steps I should be doing to ensure that this method succeeds?

Code:

private func playAppleMusic(songs : [Song]) {
    Task.init {
        do {
            print("0")
            try await SystemMusicPlayer.shared.queue.insert(songs, position: .tail)
            if (!SystemMusicPlayer.shared.isPreparedToPlay) {
                print("1")
                try await SystemMusicPlayer.shared.prepareToPlay()
            }
            print("2")
            try await SystemMusicPlayer.shared.play()
        } catch let error {
            print("playAppleMusic error: \(error.localizedDescription)")
        }
    }
}

Result:

0
1
playAppleMusic error: The operation couldn’t be completed. (MPMusicPlayerControllerErrorDomain error 1.)

Hello @funemployedin,

Thanks for your question about the new APIs available in SystemMusicPlayer on recent beta builds of iOS 15.

First, let me point out that, considering the title of this thread, you seem to be misinterpreting the logs. This indicates that isPreparedToPlay returned false, and then an error was thrown by the prepareToPlay() method.

I believe the main issue you're facing is that you never actually set the queue. Can you try simplifying your code as follows?

private func playAppleMusic(songs: [Song]) {
    Task {
        do {
            let player = SystemMusicPlayer.shared
            player.queue = MusicPlayer.Queue(for: songs)
            try await player.play()
        } catch {
            print("playAppleMusic error: \(error.localizedDescription)")
        }
    }
}

I think this will work. By the way, please note that prepareToPlay() doesn't need to be called explicitly for most cases, now that play() itself is marked as async throws.

That said, if you happened to have a single song, or a fixed number of songs you wanted to play, you could simplify it further like this:

            player.queue = [firstSong, secondSong, thirdSong]

I hope this helps.

Best regards,

Thank you, @JoeKun for taking the time to look at this and for clarifying the behavior on prepareToPlay. I modified my code to read like yours and am seeing a different error when running on my device (I am an Apple Music subscriber)

private func playAppleMusic(songs : [Song]) {
    Task.init {
        do {
            let player = SystemMusicPlayer.shared
            player.queue = MusicPlayer.Queue(for: songs)
            try await player.play()
        } catch let error {
            print("playAppleMusic error: \(error.localizedDescription)")
        }
    }
}

When running this, I see: playAppleMusic error: The operation couldn’t be completed. (MPMusicPlayerControllerErrorDomain error 6.). Do you have pointers on how to understand this error better? I'm unable to find documentation on MPMusicPlayerControllerErrorDomain.

Thank you!

Hello @funemployedin,

Thanks for the additional feedback.

The only way for us to help you diagnose this new error is for you to file a new ticket on Feedback Assistant including a sysdiagnose.

Best regards,

SystemMusicPlayer.shared.isPreparedToPlay throws
 
 
Q