I am developing an app that listens to song changes of the MPMusicPlayerController.
For that, I am adding the following observer:
NotificationCenter.default
.addObserver(self,
selector: #selector(systemSongDidChange(_:)),
name: .MPMusicPlayerControllerNowPlayingItemDidChange,
object: nil)
The problem is that, when the notification is fired, the nowPlayingItem
that can be found at (notification?.object as? MPMusicPlayerController)!.nowPlayingItem
is always nil
.
Am I doing anything wrong or is there some special trick that must be done to retrieve the actual nowPlayingItem
?
Here is a more complete code:
// ...
init() {
let systemPlayer = MPMusicPlayerController.systemMusicPlayer
NotificationCenter.default.addObserver(self,
selector: #selector(systemSongDidChange(_:)),
name: .MPMusicPlayerControllerNowPlayingItemDidChange,
object: systemPlayer)
player.beginGeneratingPlaybackNotifications()
}
private func systemSongDidChange(notification: Notification) {
let currentSong = (notification.object as? MPMusicPlayerController)?.nowPlayingItem
// `currentSong` is always `nil` =/
}
// ...
The player I am using is the Apple's Music Player. I am not playing songs from the cloud.
I have just found out why the nowPlayingItem
is always being nil
.
It seems that the user must have allowed the app to access the "Media & Apple Music". If this access has not been granted, the app will not have permission to know what is currently playing on the system's player.
This authorization can be requested as follows:
// if not yet given or requested
MPMediaLibrary.requestAuthorization { authorizationStatus in }
or
// if already requested and denied (will take user to the App Settings Page)
UIApplication.shared.openURL(URL(string:UIApplicationOpenSettingsURLString)!)