我有一个音乐应用程序,并且我想确定在关闭该应用程序时是否已暂停播放(由于诸如电话之类的事件或将AirPods拿出耳朵等)
我的第一种方法是在viewWillAppear
内运行已检查的功能
if mediaPlayer.playbackState == .paused {
...
}
如果已暂停,则更新了播放/暂停按钮图像。但是,此操作不起作用,即使已暂停,“播放/暂停”按钮仍会显示“播放”。
接下来,我尝试将观察者添加到viewDidLoad
NotificationCenter.default.addObserver(self, selector: #selector(self.wasSongInterupted(_:)), name: UIApplication.didBecomeActiveNotification, object: self.mediaPlayer)
我打电话的self.wasSongInterupted
是
@objc func wasSongInterupted(_ notification: Notification) {
DispatchQueue.main.async {
if self.mediaPlayer.playbackState == .paused {
print("paused")
self.isPlaying = false
self.playPauseSongButton.isSelected = self.isPlaying
} else if self.mediaPlayer.playbackState == .playing {
self.isPlaying = true
self.playPauseSongButton.isSelected = self.isPlaying
}
}
}
但是,我仍然遇到同样的问题。
重新打开应用程序时,确定音乐播放器是播放还是暂停的最佳方法是什么?
编辑1:我根据注释编辑了代码。
wasSongInterrupted
没有被调用,通过断点和错误,我发现代码基本上是不需要的。我将代码更改为
func wasSongInterrupted() {
DispatchQueue.main.async {
if self.mediaPlayer.playbackState == .interrupted {
var isPlaying: Bool { return self.mediaPlayer.playbackState == .playing }
print("Playback state is \(self.mediaPlayer.playbackState.rawValue), self.isPlaying Bool is \(self.isPlaying)")
self.playPauseSongButton.setImage(UIImage(named: "playIconLight"), for: .normal)
//self.playPauseSongButton.isSelected = self.isPlaying
}
}
}
在我的AppDelegate的applicationDidBecomeActive
中,
let mediaPlayerVC = MediaPlayerViewController()
mediaPlayerVC.wasSongInterupted()
现在代码可以运行了,但是我遇到了一个问题。
如果我运行以下代码:
if self.mediaPlayer.playbackState == .interrupted {
print("interrupted \(self.isPlaying)")
}
,然后拨打电话并返回到应用程序,它将到达断点。它将打印出中断以及false self.isPlaying
但是,如果我尝试通过
更新用户界面self.playPauseSongButton.isSelected = self.isPlaying
或通过
self.playPauseSongButton.setImage(UIImage(named: "playIconLight.png"), for: .normal)
我收到一条错误消息Thread 1: EXC_BREAKPOINT (code=1, subcode=0x104af9258)
答案 0 :(得分:1)
您尝试从viewWillAppear
更新播放器用户界面。来自Apple Documentation:
viewWillAppear(_:)
在将视图控制器的视图添加到视图层次结构之前,以及配置用于显示该视图的任何动画之前,将调用此方法。
因此,如果您的应用是suspended
,并且再次变成active
,则不会调用此方法,因为您的UIViewController
已经在Navigations Stack
。
如果您想抓住应用程序从active
状态变为suspended
的时刻,则需要使用AppDelegate
。来自Apple Documentation:
applicationDidBecomeActive(_:)
调用此方法是为了让您的应用知道它已从非活动状态变为活动状态。发生这种情况的原因是您的应用是由用户或系统启动的。
因此,您需要在AppDelegate
处使用此方法来处理应用程序的运行并更新您的界面。
更新
您在说自己正在使用的AppDelegate
方法的内部
let mediaPlayerVC = MediaPlayerViewController()
mediaPlayerVC.wasSongInterupted()
那是错误的,因为您正在创建新的视图控制器。您需要做的是从导航堆栈访问您的现有视图控制器并进行更新。
可能的解决方案之一是使用NotificationCenter
发送通知。您当然应该订阅该事件的控制器。
首先,您需要创建一个通知名称
extension Notification.Name {
static let appBecameActive = Notification.Name(rawValue: "appBecameActive")
}
然后在您的AppDelegate
中添加以下代码,以在应用程序激活时发布通知
func applicationDidBecomeActive(_ application: UIApplication) {
NotificationCenter.default.post(name: .appBecameActive, object: nil)
}
最后在您的视图控制器中添加以订阅通知
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self,
selector: #selector(wakeUp),
name: .appBecameActive,
object: nil)
...
}
@objc func wakeUp() {
// Update your UI from here
}
希望它对您有帮助。