如何在 Swift 3 中正确设置 MPNowPlayingInfoCenter

How to properly set up the MPNowPlayingInfoCenter in Swift 3

(tl;dr 在底部)

目前我正在通过以下方式设置属性:

let mpic = MPNowPlayingInfoCenter.default()
func setInfoCenterCredentials(_ postion: NSNumber, _ duration: NSNumber, _ playbackState: Int) {

    let mySize = CGSize(width: 400, height: 400)
    let albumArt = MPMediaItemArtwork(boundsSize:mySize) { sz in
        return getCoverImage()
    }
    mpic.nowPlayingInfo = [MPMediaItemPropertyTitle: globalTrackName,
                           MPMediaItemPropertyArtist: globalArtistName,
                           MPMediaItemPropertyArtwork: albumArt,
                           MPNowPlayingInfoPropertyElapsedPlaybackTime: postion,
                           MPMediaItemPropertyPlaybackDuration: duration,
                           MPNowPlayingInfoPropertyPlaybackRate: playbackState]
}

与 Spotify iOS SDK 一起使用:

func audioStreaming(_ audioStreaming: SPTAudioStreamingController, didChangePosition position: TimeInterval) {
    if self.isChangingProgress {
        return
    }
    let position = Float(positionDouble / durationDouble)
    let duration = Float((sptAudioStreamCtr?.metadata.currentTrack!.duration)!)    
    globalPositionNumber = NSNumber(value: position)
    globalDurationNumber = NSNumber(value: duration)

    setInfoCenterCredentials(globalPositionNumber, globalDurationNumber, 1)
}

到目前为止效果很好。

问题 #1

当我按下暂停键时:

音乐停止,但时间还在倒计时。我已经在他们的 didSet 上打印了 globalPositionNumberglobalDurationNumber 并且他们没有得到改变。不出所料。

那我实现了:

func audioStreaming(_ audioStreaming: SPTAudioStreamingController, didChangePlaybackStatus isPlaying: Bool) {

    if !isPlaying {
        setInfoCenterCredentials(globalPositionNumber, globalDurationNumber, 0)
    }
}

现在有问题。点击暂停,导致计时器被重置并从 0 开始,一旦恢复。

问题#2

如果我在应用程序中向上滑动控制面板,计数器会同步。如果我使用主页按钮离开应用程序并从主屏幕向上滑动控制面板,计数器会从零开始计数。

问题#3

如果我从主屏幕点击 pause/forward/back 按钮,它们运行良好。如果我在我的应用程序处于活动状态的情况下向上滑动控制面板并按下按钮,则没有任何反应。

我错过了什么?非常感谢帮助

tl;dr

问题 1: 控制面板的时间计数器使用 MPNowPlayingInfoPropertyPlaybackRate 1 重置或如果未设置则不停止。

问题 2:如果在曲目期间离开应用程序,时间计数器从零开始。

问题 3:在应用程序处于活动状态时点击控制面板上的操作按钮没有任何效果。

编辑:

override var canBecomeFirstResponder : Bool {
    return true
}

override func remoteControlReceived(with event: UIEvent?) {

    if let ctr = SPTAudioHandler.shared.audioCtrl {
        let rc = event!.subtype
        switch rc {
        case .remoteControlTogglePlayPause:
            ctr.setIsPlaying(!ctr.playbackState.isPlaying, callback: nil)
        case .remoteControlPlay:
            ctr.setIsPlaying(!ctr.playbackState.isPlaying, callback: nil)
        case .remoteControlPause:
            ctr.setIsPlaying(!ctr.playbackState.isPlaying, callback: nil)
        case .remoteControlNextTrack:
            globalBackForthInt = 1
            getNextSpotifyTrack(SPTAudioHandler.shared.spotifyTracks, SPTAudioHandler.shared.playerView)
            globalTrackIndexPath = globalTrackIndexPath + 1
        case .remoteControlPreviousTrack:
            getNextSpotifyTrack(SPTAudioHandler.shared.spotifyTracks, SPTAudioHandler.shared.playerView)
            globalBackForthInt = -1
            getNextSpotifyTrack(SPTAudioHandler.shared.spotifyTracks, SPTAudioHandler.shared.playerView)
            globalTrackIndexPath = globalTrackIndexPath - 1
        default:
            break
        }
    }
}

其他一切都在 setInfoCenterCredentials

中设置

I would suggest re-importing the framework to ensure there are no issues with integration.

由于 GitHub 上没有负面报告,代码看起来也不错,这可能只是一个集成问题。

希望这对您有所帮助:)

答案更简单...

这是模拟器的问题...所有错误仅出现在模拟器上。 一切 在实际设备上运行良好。