How to get Song Information From Queue?

I have a recent post kind of outlining a similar question here. This time though I'm confident that inserting an array of Track works when inserting into the ApplicationMusicPlayer.shared.queue but now I'm not sure how I can initialize the queue to display song title and artwork for example. I'm also not sure how to get the current item in the queue's artist information and album information which I feel should be easy to do so maybe I'm missing something obvious. Hope this paints of what I'm trying to do and I'm going to post the neccessary code here to help me debug/figure out this problem.

import SwiftUI
import MusicKit

struct PlayBackView: View {
    @Environment(\.scenePhase) var scenePhase
    @Environment(\.openURL) private var openURL
    
    // Adding Enum Here for Question Sake
    enum PlayState {
        case play
        case pause
    }
    
    @State var song: Track
    @Binding var songs: [Track]?
    @State var isShuffled = false
    @State private var playState: PlayState = .pause
    @State private var songTimer: Int = Int.random(in: 5...30)
    @State private var roundTimer: Int = 5
    @State private var isTimerActive = false
    //  @State private var volumeValue = VolumeObserver()
    @State private var isFirstPlay = true
    @State private var isDancing = false
    
    
    @State private var player = ApplicationMusicPlayer.shared
    
    private var isPlaying: Bool {
        return (player.state.playbackStatus == .playing)
    }
    
    let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
    
    var playPauseImage: String {
        switch playState {
            case .play:
            "pause.fill"
            case .pause:
            "play.fill"
        }
    }
    
    var body: some View {
        VStack {
            
            // Album Cover
            HStack(spacing: 20) {
                if let artwork = player.queue.currentEntry?.artwork {
                    ArtworkImage(artwork, height: 100)
                } else {
                    Image(systemName: "music.note")
                    .resizable()
                    .frame(width: 100, height: 100)
                }
                
                VStack(alignment: .leading) {
                    
                    /* 
                    This is where I want to display song title, album title, and artist name for example
                    
                    */
                    
                    // Song Title
                    Text(player.queue.currentEntry?.title ?? "Unable to Find Song Title")
                    .font(.title)
                    .fixedSize(horizontal: false, vertical: true)
                    
                    // Album Title
                    //                    Text(player.queue.currentEntry ?? "Album Title Not Found")
                    //                        .font(.caption)
                    //                        .fixedSize(horizontal: false, vertical: true)
                    
                    // I don't know what the subtitle actually grabs
                    Text(player.queue.currentEntry?.subtitle ?? "Artist Name Not Found")
                    .font(.caption)
                }
            }
            .padding()
            
            // Play/Pause Button
            Button(action: {
                handlePlayButton()
                isFirstPlay = false
            }, label: {
                Text(playState == .play ? "Pause" : isFirstPlay ? "Play" : "Resume")
                .frame(maxWidth: .infinity)
            })
            .buttonStyle(.borderedProminent)
            .padding()
            .font(.largeTitle)
            .tint(.red)
        }
        .padding()
        // Maybe I should use the `.task` modifier here?
        .onAppear {
            // I'm sure this code could be improved but don't think it'll help answer the question at the moment.
            Task {
                if let songs = songs {
                    do {
                        if isShuffled {
                            let shuffledSongs = songs.shuffled()
                            try await player.queue.insert(shuffledSongs, position: .tail)
                            handlePlayButton()
                        } else {
                            try await player.queue.insert(songs, position: .tail)
                        }
                    } catch {
                        print(error.localizedDescription)
                    }
                }
            }
        }
    }
    
    private func handlePlayButton() {
        Task {
            if isPlaying {
                player.pause()
                playState = .pause
                isTimerActive = false
            } else {
                playState = .play
                await playTrack()
                isTimerActive = true
            }
        }
    }
    
    @MainActor
    private func playTrack() async {
        do {
            try await player.play()
        } catch {
            print(error.localizedDescription)
        }
    }
}

//#Preview {
//    PlayBackView()
//} 
Answered by Engineer in 809604022

Hello @JB184351, thank you for your post. If the currentEntry's item is a Song, for example, you can access it like so:

switch musicPlayer.queue.currentEntry?.item {
    case .song(let song):
        let title = song.title
        // get other properties
    default:
        break
}

Note that the item can also be a MusicVideo. You can handle this case in a similar fashion, by adding case .musicVideo(let musicVideo): to the above switch statement.

Accepted Answer

Hello @JB184351, thank you for your post. If the currentEntry's item is a Song, for example, you can access it like so:

switch musicPlayer.queue.currentEntry?.item {
    case .song(let song):
        let title = song.title
        // get other properties
    default:
        break
}

Note that the item can also be a MusicVideo. You can handle this case in a similar fashion, by adding case .musicVideo(let musicVideo): to the above switch statement.

Oh!! I remember reading that it was an enum in the docs but my brain didn't think of using a Switch statement like this 🤦🏼‍♂️. Thank you for your response. This answers my question.

How to get Song Information From Queue?
 
 
Q