iOS MPMusicPlayerController歌曲更改通知没有歌曲对象

时间:2018-12-05 15:24:14

标签: ios swift mpmusicplayercontroller

我正在开发一个监听MPMusicPlayerController歌曲更改的应用。

为此,我添加了以下观察者:

NotificationCenter.default
    .addObserver(self,
                 selector: #selector(systemSongDidChange(_:)),
                 name: .MPMusicPlayerControllerNowPlayingItemDidChange,
                 object: nil)

问题在于,当触发通知时,在nowPlayingItem处可以找到的(notification?.object as? MPMusicPlayerController)!.nowPlayingItem总是nil

我做错了什么吗,或者必须采取一些特殊的技巧来检索实际的nowPlayingItem

这是更完整的代码:

// ...
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` =/
}
// ...

我正在使用的播放器是Apple的Music Player。我不是在播放云端歌曲。

2 个答案:

答案 0 :(得分:0)

您需要在通知中设置对象,才能获取nowPlayingItem

代码应如下所示:

private let playerController = MPMusicPlayerController.applicationMusicPlayer

NotificationCenter.default.addObserver(
    self,
    selector: #selector(systemSongDidChange(_:)),
    name: .MPMusicPlayerControllerNowPlayingItemDidChange,
    object: playerController
)

然后,您应该可以在systemSongDidChange函数中像这样访问nowPlayingItem

func systemSongDidChange(_ notification: Notification) {
    guard let playerController = notification?.object as? MPMusicPlayerController else {
        return
    }
    let item = playerController.nowPlayingItem
}

答案 1 :(得分:0)

我刚刚发现了为什么nowPlayingItem总是nil的原因。

似乎用户必须已允许该应用访问“媒体和Apple音乐”。如果未授予此访问权限,则该应用将无权知道系统播放器上当前正在播放的内容。

可以按以下方式请求此授权:

// if not yet given or requested
MPMediaLibrary.requestAuthorization { authorizationStatus in }

// if already requested and denied (will take user to the App Settings Page)
UIApplication.shared.openURL(URL(string:UIApplicationOpenSettingsURLString)!)