我正在尝试做一个可以让计时器在后台运行的应用程序.
这是我的代码:
let taskManager = Timer.scheduledTimer(timeInterval: 10, target: self, selector: #selector(self.scheduleNotification), userInfo: nil, repeats: true)
RunLoop.main.add(taskManager, forMode: RunLoopMode.commonModes)
Run Code Online (Sandbox Code Playgroud)
上面的代码将执行一个将调用本地通知的函数.当应用程序处于前台时,这是有效的,如何让它在后台运行?
我试图放几条打印线,我看到当我最小化(按下主页按钮)应用程序时,计时器停止,当我回到应用程序时,它恢复.
我希望计时器仍然在后台运行.有办法吗?
这就是我想要发生的事情:
运行应用程序 - >等待10秒 - >收到通知 - >等待10秒 - >收到通知 - >然后返回等待再次收到
在前景时发生.但不是在后台.请帮助.
Dar*_*ary 20
斯威夫特 4、斯威夫特 5
我更喜欢不在后台任务上运行计时器,只需比较 applicationDidEnterBackground 和 applicationWillEnterForeground 之间的日期秒数。
func setup() {
NotificationCenter.default.addObserver(self, selector: #selector(applicationDidEnterBackground(_:)), name: UIApplication.didEnterBackgroundNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(applicationWillEnterForeground(_:)), name: UIApplication.willEnterForegroundNotification, object: nil)
}
@objc func applicationDidEnterBackground(_ notification: NotificationCenter) {
appDidEnterBackgroundDate = Date()
}
@objc func applicationWillEnterForeground(_ notification: NotificationCenter) {
guard let previousDate = appDidEnterBackgroundDate else { return }
let calendar = Calendar.current
let difference = calendar.dateComponents([.second], from: previousDate, to: Date())
let seconds = difference.second!
countTimer -= seconds
}
Run Code Online (Sandbox Code Playgroud)
Far*_*rzi 14
您可以转到功能并打开后台模式和活动音频.AirPlay,图片和图片.
真的行 .你不需要设置DispatchQueue.你可以使用Timer.
Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { (t) in
print("time")
}
Run Code Online (Sandbox Code Playgroud)
Ari*_*gal 10
这有效。正如另一个答案中所建议的,它在异步任务中使用 while 循环,但它也包含在后台任务中
func executeAfterDelay(delay: TimeInterval, completion: @escaping(()->Void)){
backgroundTaskId = UIApplication.shared.beginBackgroundTask(
withName: "BackgroundSound",
expirationHandler: {[weak self] in
if let taskId = self?.backgroundTaskId{
UIApplication.shared.endBackgroundTask(taskId)
}
})
let startTime = Date()
DispatchQueue.global(qos: .background).async {
while Date().timeIntervalSince(startTime) < delay{
Thread.sleep(forTimeInterval: 0.01)
}
DispatchQueue.main.async {[weak self] in
completion()
if let taskId = self?.backgroundTaskId{
UIApplication.shared.endBackgroundTask(taskId)
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
只有满足以下两个条件时,计时器才能在后台运行:
您的应用程序由于其他原因在后台运行.(大多数应用程序不会;大多数应用程序在进入后台时会被暂停.)并且:
当应用程序进入后台时,计时器已经运行.
小智 3
计时器无法在后台运行。对于后台任务,您可以检查下面的链接...
https://www.raywenderlich.com/143128/background-modes-tutorial-getting-started
| 归档时间: |
|
| 查看次数: |
27362 次 |
| 最近记录: |