MusicKit Get song from SystemMusicPlayer.Queue often Error

I want get song object from SystemMusicPlayer.Queue use musickit . But there's often crash .

Here is my code

  func getSongData(complection:@escaping (Song)->())
  {

    Task.detached {
      
      do {
   
        let queue : SystemMusicPlayer.Queue?
         
        queue = SystemMusicPlayer.shared.queue
         
        if queue?.currentEntry != nil
        {
          let request = MusicCatalogResourceRequest<Song>(matching: \.id, equalTo: MusicItemID(rawValue: queue?.currentEntry?.item?.id.rawValue ?? "1595045323"))
          let response = try? await request.response()
        
          complection((response?.items.first)!)
        }

    }
  
  }
  
  }
Answered by Frameworks Engineer in 712691022

Hello @zengxing,

The SystemMusicPlayer API is meant to be used on the MainActor.

Hence, you should try to setup your tasks with the @MainActor keyword, like:

Task.detached { @MainActor in
    …
}

or even more simply:

Task { @MainActor in
    …
}

But more importantly, you don't need to any of this to get access to a Song from the queue. Instead, you can simply check the current entry's item, and get the underlying song from it:

You could just do this:

    private var currentlyPlayingSong: Song? {
        var currentlyPlayingSong: Song?
        let musicPlayerQueue = SystemMusicPlayer.shared.queue
        if let currentEntry = musicPlayerQueue.currentEntry {
            if case .song(let song) = currentEntry.item {
                currentlyPlayingSong = song
            }
        }
        return currentlyPlayingSong
    }

I hope it helps.

Best regards,

Accepted Answer

Hello @zengxing,

The SystemMusicPlayer API is meant to be used on the MainActor.

Hence, you should try to setup your tasks with the @MainActor keyword, like:

Task.detached { @MainActor in
    …
}

or even more simply:

Task { @MainActor in
    …
}

But more importantly, you don't need to any of this to get access to a Song from the queue. Instead, you can simply check the current entry's item, and get the underlying song from it:

You could just do this:

    private var currentlyPlayingSong: Song? {
        var currentlyPlayingSong: Song?
        let musicPlayerQueue = SystemMusicPlayer.shared.queue
        if let currentEntry = musicPlayerQueue.currentEntry {
            if case .song(let song) = currentEntry.item {
                currentlyPlayingSong = song
            }
        }
        return currentlyPlayingSong
    }

I hope it helps.

Best regards,

MusicKit Get song from SystemMusicPlayer.Queue often Error
 
 
Q