sim*_*ley 3 mpmusicplayercontroller ios swift
我正在使用 MPMusicPlayerController 在我的应用程序中创建一个音乐播放器。除了一个小问题外,我一切都很好:
当歌曲自然变化时 - 一首歌曲结束,下一首歌曲从设置的队列开始 - 通知MPMusicPlayerControllerNowPlayingItemDidChange似乎不会被调用。
目前我正在使用MPMusicPlayerControllerNowPlayingItemDidChange和MPMusicPlayerControllerPlaybackStateDidChange通知。这些包括播放、暂停、随机播放、重复、下一首、上一首等。当点击通知时,我会根据 MPMusicPlayerController 刷新屏幕以显示所需的新歌曲、艺术家或不同的按钮图标。但是,当一首歌曲结束并且下一首歌曲自动开始播放时,这些都不会被调用——这意味着上一首歌曲的标题和艺术家会被保留,直到用户重新加载屏幕或与音频控件交互,这不是很好的用户体验。
没有定期检查当前名称是否与播放名称匹配,我不知道如何在应用程序的正常流程中更新它。
NotificationCenter.default.addObserver(
forName: NSNotification.Name.MPMusicPlayerControllerNowPlayingItemDidChange,
object: musicPlayerController,
queue: nil) { _ in
// Update view
}
Run Code Online (Sandbox Code Playgroud)
The answer to this turns out to be very simple but also difficult to spot if you're not looking in the right place.
Before we add our observers we need to begin generating the playback notifications:
musicPlayerController.beginGeneratingPlaybackNotifications()
NotificationCenter.default.addObserver(self,
selector: #selector(refreshView),
name: .MPMusicPlayerControllerPlaybackStateDidChange,
object: musicPlayerController)
NotificationCenter.default.addObserver(self,
selector: #selector(refreshView),
name: .MPMusicPlayerControllerNowPlayingItemDidChange,
object: musicPlayerController)
Run Code Online (Sandbox Code Playgroud)
We also need to remember to end generating them when we leave (deallocate) the view:
deinit {
NotificationCenter.default.removeObserver(self, name: .MPMusicPlayerControllerPlaybackStateDidChange, object: nil)
NotificationCenter.default.removeObserver(self, name: .MPMusicPlayerControllerNowPlayingItemDidChange, object: nil)
musicPlayerController.endGeneratingPlaybackNotifications()
}
Run Code Online (Sandbox Code Playgroud)
The confusion came from the musicMediaPlayer returning a number of notifications even without this which didn't point to the fact we weren't observing all the notifications that were being fired.
Note: It is worth noting that as of the time of writing this it was in discussion whether there was a need to manually remove observers - I have included it here for answer completeness.