我有一个应用程序,由于它播放音乐,往往会在后台保持清醒;但是,在极少数情况下,如果音乐在歌曲之间停止的时间超过预期(可能是相对较短的时间),由于连接问题或用户将音乐静音,应用程序将被暂停。我知道UIApplicationExitOnSuspend
但不像它的描述,这实际上是在进入背景时退出。我做了大量的研究,我知道没有系统通知可以进入暂停状态。
无论如何都要确定离开暂停状态该应用已暂停?或者,无论如何都要做类似于UIApplicationExitOnSuspend
的事情,除非应用程序实际上被暂停,而不仅仅是当它进入后台时?
答案 0 :(得分:1)
您可以尝试在UIApplication上使用backgroundtimeremaining
属性,在某个时间间隔内使用计时器轮询它,并且该值应该足够接近零 - 设置一个标志,甚至是userDefaults中的值,您可以然后回到前台后检查并取消设置?
此属性包含应用程序必须在后台运行的时间,才能被系统强制终止。当应用程序在前台运行时,此属性中的值仍然适当大。如果应用程序使用beginBackgroundTask(expirationHandler :)方法启动一个或多个长时间运行的任务,然后转换为后台,则会调整此属性的值以反映应用程序剩余运行的时间。
答案 1 :(得分:0)
我最终创建了一个小类,以确定应用程序何时进入暂停状态:
class SuspendedMonitor {
static let shared = SuspendedMonitor()
var delegate: SuspendedMonitorDelegate?
private let Interval = 10.0
private let MaxDelta = 2.0
private var _timestamp: Double
private var _timer: Timer?
private init() {
_timestamp = timeInMs()
}
public func start() {
_timestamp = timeInMs()
NotificationCenter.default.addObserver(
self,
selector: #selector(enterForeground),
name: NSNotification.Name.UIApplicationWillEnterForeground,
object: nil
)
NotificationCenter.default.addObserver(
self,
selector: #selector(enterBackground),
name: NSNotification.Name.UIApplicationDidEnterBackground,
object: nil
)
}
@objc func enterForeground() {
checkSync()
_timer?.invalidate()
}
@objc func enterBackground() {
_timestamp = timeInMs()
setupTimer()
}
@objc func incrementTime() {
_timestamp = _timestamp + (Interval * 1000)
}
private func setupTimer() {
_timer = Timer.scheduledTimer(
timeInterval: Interval,
target: self,
selector: #selector(incrementTime),
userInfo: nil,
repeats: true
)
}
private func checkSync() {
if timeInMs() - _timestamp > ((Interval + MaxDelta) * 1000) { appSuspended() }
}
private func appSuspended() {
delegate?.appDidSuspend(self)
}
}
protocol SuspendedMonitorDelegate: class {
func appDidSuspend(_ monitor: SuspendedMonitor)
}