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
变量显示新的,trackNum
而MPNowPlayingInfoCenter.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().nowPlayingInfo
到nowPlayingInfo
,然后曲目编号正确更新锁屏上.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
触发AVPlayerItemDidPlayToEndTimeNotification
的playerTimeJumped
方法触发的方法中AVPlayerItemTimeJumpedNotification
.
这会导致竞争状况.更多细节由苹果公司的工作人员提供了这里.
可以通过保留nowPlayingInfo
根据需要更新的本地字典并始终MPNowPlayingInfoCenter.defaultCenter().nowPlayingInfo
从中设置而不是设置单个值来解决该问题.