MPNowPlayingInfoCenter nowPlayingInfo在轨道末尾不更新

Hél*_*tin 13 ios mpnowplayinginfocenter swift

我有一个方法可以改变我的应用程序播放的音轨,AVPlayer并设置MPNowPlayingInfoCenter.defaultCenter().nowPlayingInfo新的音轨:

func setTrackNumber(trackNum: Int) {
    self.trackNum = trackNum
    player.replaceCurrentItemWithPlayerItem(tracks[trackNum])

    var nowPlayingInfo: [String: AnyObject] = [ : ]        
    nowPlayingInfo[MPMediaItemPropertyAlbumTitle] = tracks[trackNum].albumTitle
    nowPlayingInfo[MPMediaItemPropertyTitle] = "Track \(trackNum)"
    ...
    MPNowPlayingInfoCenter.defaultCenter().nowPlayingInfo = nowPlayingInfo 

    print("Now playing local: \(nowPlayingInfo)")
    print("Now playing lock screen: \(MPNowPlayingInfoCenter.defaultCenter().nowPlayingInfo)")   
}
Run Code Online (Sandbox Code Playgroud)

当用户明确选择专辑或曲目并且曲目结束并且下一曲目自动开始时,我会调用此方法.锁定屏幕在用户设置专辑或曲目时正确显示曲目元数据,但在曲目结束且自动设置下一曲目时不正确.

我添加了print语句以确保我正确填充nowPlayingInfo字典.正如所料,当调用此方法进行用户启动的专辑或曲目更改时,两个打印语句会打印相同的字典内容.但是,在自动跟踪更改后调用方法的情况下,局部nowPlayingInfo变量显示新的,trackNumMPNowPlayingInfoCenter.defaultCenter().nowPlayingInfo显示前一个trackNum:

Now playing local: ["title": Track 9, "albumTitle": Test Album, ...]
Now playing set: Optional(["title": Track 8, "albumTitle": Test Album, ...]
Run Code Online (Sandbox Code Playgroud)

我发现,当我设置就行了断点,设置MPNowPlayingInfoCenter.defaultCenter().nowPlayingInfonowPlayingInfo,然后曲目编号正确更新锁屏上.sleep(1)在该行之后添加也确保锁定屏幕上的轨道被正确更新.

我已经确认nowPlayingInfo总是从主队列设置.我已经尝试在主队列或不同队列中显式运行此代码,但行为没有变化.

什么阻止我改变MPNowPlayingInfoCenter.defaultCenter().nowPlayingInfo?如何确保设置MPNowPlayingInfoCenter.defaultCenter().nowPlayingInfo始终更新锁定屏幕信息?

编辑

在经历了第N次思考"并发"的代码之后,我找到了罪魁祸首.我不知道为什么我之前没有对此表示怀疑:

func playerTimeJumped() {
    let currentTime = currentItem().currentTime()

    dispatch_async(dispatch_get_main_queue()) {
        MPNowPlayingInfoCenter.defaultCenter().nowPlayingInfo?[MPNowPlayingInfoPropertyElapsedPlaybackTime] = CMTimeGetSeconds(currentTime)
    }
}

NSNotificationCenter.defaultCenter().addObserver(
       self,
       selector: "playerTimeJumped",
       name: AVPlayerItemTimeJumpedNotification,
       object: nil)
Run Code Online (Sandbox Code Playgroud)

此代码更新锁定屏幕在用户擦洗或向前/向后跳过时所经过的时间.如果我将其评论出来,则nowPlayingInfo更新setTrackNumber将在任何条件下按预期工作.

修改过的问题:这两段代码在主队列上运行时如何交互?有什么方法可以让我nowPlayingInfo更新,AVPlayerItemTimeJumpedNotification因为有一个呼叫时会有跳转setTrackNumber

Hél*_*tin 10

问题是nowPlayingInfo当轨道自动改变时,在两个地方同时更新:在由setTrackNumber触发AVPlayerItemDidPlayToEndTimeNotificationplayerTimeJumped方法触发的方法中AVPlayerItemTimeJumpedNotification.

这会导致竞争状况.更多细节由苹果公司的工作人员提供了这里.

可以通过保留nowPlayingInfo根据需要更新的本地字典并始终MPNowPlayingInfoCenter.defaultCenter().nowPlayingInfo从中设置而不是设置单个值来解决该问题.