最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

ios - Refresh a var containing a song title when the song ends? - Stack Overflow

programmeradmin1浏览0评论

I am trying to have Text() reflect the current playing song on my device (songTitle), and I can't seem to find an answer anywhere shockingly This is my main handler class

let musicPlayer = MPMusicPlayerController.systemMusicPlayer
var songTitle = musicPlayer.nowPlayingItem?.title ?? "No song playing"


class MusicMonitor: ObservableObject {
    private let player = MPMusicPlayerController.systemMusicPlayer
    
    init() {
        NotificationCenter.default.addObserver(
            forName: .MPMusicPlayerControllerNowPlayingItemDidChange,
            object: player,
            queue: OperationQueue.main) { (note) in
                self.updateCurrentSong()
                printTest(inp:("Song changed " + (self.player.nowPlayingItem?.title ?? "No song playing")))
        }
        
        player.beginGeneratingPlaybackNotifications()
        updateCurrentSong() // Get initial song
    }
    
    private func updateCurrentSong() {
        if let nowPlayingItem = player.nowPlayingItem {
            songTitle = nowPlayingItem.title ?? "No song playing" // Your next song logic here
        }
    }
    
    deinit {
        player.endGeneratingPlaybackNotifications()
    }
}

This is mostly code that I've pieced together from other forums, but it doesn't seem to update at all when the song changes. It gets the song right initially when you open the app, but never updates.

I am also aware there are a ton of redundant vars, I am just learning swift/swiftui, so I will go back and clean it up once I am more familiar and I know I won't break everything

My current try is updating it with the NotificationCenter observers but those don't seem to work. I have also tried a method with getting the duration of the song, but it kind of breaks when you skip in the song. It does work updating it manually with a button press, but it doesn't do what I need it to do, since ideally it doesn't involve user interaction.

Any help would be greatly appreciated!

I am trying to have Text() reflect the current playing song on my device (songTitle), and I can't seem to find an answer anywhere shockingly This is my main handler class

let musicPlayer = MPMusicPlayerController.systemMusicPlayer
var songTitle = musicPlayer.nowPlayingItem?.title ?? "No song playing"


class MusicMonitor: ObservableObject {
    private let player = MPMusicPlayerController.systemMusicPlayer
    
    init() {
        NotificationCenter.default.addObserver(
            forName: .MPMusicPlayerControllerNowPlayingItemDidChange,
            object: player,
            queue: OperationQueue.main) { (note) in
                self.updateCurrentSong()
                printTest(inp:("Song changed " + (self.player.nowPlayingItem?.title ?? "No song playing")))
        }
        
        player.beginGeneratingPlaybackNotifications()
        updateCurrentSong() // Get initial song
    }
    
    private func updateCurrentSong() {
        if let nowPlayingItem = player.nowPlayingItem {
            songTitle = nowPlayingItem.title ?? "No song playing" // Your next song logic here
        }
    }
    
    deinit {
        player.endGeneratingPlaybackNotifications()
    }
}

This is mostly code that I've pieced together from other forums, but it doesn't seem to update at all when the song changes. It gets the song right initially when you open the app, but never updates.

I am also aware there are a ton of redundant vars, I am just learning swift/swiftui, so I will go back and clean it up once I am more familiar and I know I won't break everything

My current try is updating it with the NotificationCenter observers but those don't seem to work. I have also tried a method with getting the duration of the song, but it kind of breaks when you skip in the song. It does work updating it manually with a button press, but it doesn't do what I need it to do, since ideally it doesn't involve user interaction.

Any help would be greatly appreciated!

Share Improve this question edited Feb 1 at 7:56 Joakim Danielson 52.1k5 gold badges33 silver badges71 bronze badges asked Feb 1 at 0:10 OliemanqOliemanq 212 bronze badges 2
  • In your MusicMonitor add @Published var songTitle: String = "" and update this wherever it is needed (eg in updateCurrentSong()). Declare @StateObject private var musicMonitor = MusicMonitor() in the parent View, and pass this model to other views. Then use Text(musicMonitor.songTitle) in your View. For iOS16, see Apple Monitoring data, for iOS17+ see Managing model data in your app – workingdog support Ukraine Commented Feb 1 at 0:47
  • @workingdogsupportUkraine Thanks, this worked! I figured it would be something to do with the variable and me not calling it properly with the classes, and this made sense! – Oliemanq Commented Feb 1 at 3:50
Add a comment  | 

1 Answer 1

Reset to default 0

In your MusicMonitor add:

@Published var songTitle: String = ""

And set this wherever it is changed (eg in updateCurrentSong()). In the parent View declare:

@StateObject private var musicMonitor = MusicMonitor()

And pass this model to other Views. Then in your View use:

Text(musicMonitor.songTitle)`

For iOS16, see Apple Monitoring data, for iOS17+ see Managing model data in your app – workingdog support Ukraine

发布评论

评论列表(0)

  1. 暂无评论