Swift - 使用计时器检测用户不活动,然后在 4 分钟后显示警报以提示用户是不是仍然存在
Posted
技术标签:
【中文标题】Swift - 使用计时器检测用户不活动,然后在 4 分钟后显示警报以提示用户是不是仍然存在【英文标题】:Swift - Using a Timer to detect user inactivity then display an Alert after 4 minutes to prompt the user if they are still thereSwift - 使用计时器检测用户不活动,然后在 4 分钟后显示警报以提示用户是否仍然存在 【发布时间】:2019-12-11 11:01:45 【问题描述】:我有一个包含 4 个视图的 iPad 基本应用程序。在整个应用程序中,我希望能够检测到用户不活动,然后在 4 分钟后显示警报,询问用户他们是否还在那里。
我为Timer 和Alert 函数找到了一些有用的资源。我已经玩过这些教程,并且可以让 Timer 自己工作。但是,这是我第一次在 Swift 中开发,所以我想要一些关于将 Timer 连接到 Alert 的最佳方法的指导是?我希望计时器运行 4 分钟,然后创建警报。
我还想知道将这些元素的代码放在哪里最好,这样它们就可以在我的所有 4 个视图中工作。例如,是否有一个地方可以放置代码并重用它,而不是在 4 个视图中的每一个中重复它?
【问题讨论】:
我不明白为什么人们为这个问题投票。 【参考方案1】:首先,您可以按照此处的说明设置计时器:https://blog.gaelfoppolo.com/detecting-user-inactivity-in-ios-application-684b0eeeef5b
然后你可以做这样的事情来处理超时通知:
extension UIViewController
func observeTimeout()
NotificationCenter.default.addObserver(
self,
selector: #selector(handleTimeout),
name: .appTimeout,
object: nil)
@objc func handleTimeout()
let alert = UIAlertController(title: "Timeout", message: "Oh no!", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: _ in
))
present(alert, animated: true, completion: nil)
然后在您的每个视图控制器中执行此操作以注册超时:
class SomeViewController: UIViewController
override func viewDidLoad()
super.viewDidLoad()
observeTimeout()
【讨论】:
【参考方案2】:然而,这个问题被问到已经有一段时间了,因为我遇到了同样的问题,所以我稍微改变了@rob-c 使用this guide 提供的答案:
在 Swift 5.5 和 iOS 15.1 上测试
1- 创建 UIApplication 的子类
import Foundation
import UIKit
class TimerApplication: UIApplication
private var timeoutInSeconds: TimeInterval
return 40.0
private var idleTimer: Timer?
override init()
super.init()
resetIdleTimer()
private func resetIdleTimer()
if let idleTimer = idleTimer
idleTimer.invalidate()
idleTimer = Timer.scheduledTimer(timeInterval: timeoutInSeconds,
target: self,
selector: #selector(TimerApplication.timeHasExceeded),
userInfo: nil,
repeats: false
)
@objc private func timeHasExceeded()
NotificationCenter.default.post(name: .appTimeout, object: nil)
override func sendEvent(_ event: UIEvent)
super.sendEvent(event)
if idleTimer != nil
self.resetIdleTimer()
if let touches = event.allTouches
for touch in touches where touch.phase == UITouch.Phase.began
self.resetIdleTimer()
2- 添加通知名称
import Foundation
extension Notification.Name
static let appTimeout = Notification.Name("appTimeout")
3- 创建 main.swift 文件并添加这个
import Foundation
import UIKit
/// NOTE: comment out @UIApplicationMain in AppDelegate
UIApplicationMain(
CommandLine.argc,
CommandLine.unsafeArgv,
NSStringFromClass(TimerApplication.self),
NSStringFromClass(AppDelegate.self)
)
4- 从 AppDelegate 中移除 @UIApplicationMain
5- 为通知添加观察者
在 AppDelegate 或任何视图控制器中根据您的情况添加观察者:
func addObservers()
NotificationCenter.default.addObserver(self,
selector: #selector(idleTimeLimitReached(_:)),
name: .appTimeout,
object: nil)
@objc func idleTimeLimitReached(_ notification: Notification)
print("***** IDLE Time called")
【讨论】:
【参考方案3】:您可以在 AppDelegate 本身中运行 Timer 并从 AppDelegate 显示如下所示的警报
func showAlertFromAppDelegates()
let alertVC = UIAlertController(title: "Oops" , message: "Presented Alert from AppDelegates", preferredStyle: UIAlertController.Style.alert)
let okAction = UIAlertAction(title: "Okay", style: UIAlertAction.Style.cancel) (alert) in
alertVC.addAction(okAction)
var presentVC = self.window!.rootViewController
while let next = presentVC?.presentedViewController
presentVC = next
presentVC?.present(alertVC, animated: true, completion: nil)
编辑: 添加了定时器相关代码,当你想开始不活动时调用 startTimer(),当不活动结束时调用 stopTimer()
func startTimer()
let interval = 4*60
timer = Timer.scheduledTimer(timeInterval: TimeInterval(interval), target: self, selector: #selector(self.showAlertFromAppDelegates), userInfo: nil, repeats: true)
func stopTimer()
if let timer = timer
timer.invalidate()
timer = nil
【讨论】:
如何检测不活动? 我的答案是“我想要一些关于将计时器连接到警报的最佳方式的指导”。 我的假设是他知道如何检测不活动,他只需要帮助来管理计时器和警报。 好吧,我不同意这一点,但让我们看看 OP 是否会做出一些澄清。 好吧,他明确表示“我还想知道将这些元素的代码放在哪里最好,以便它们适用于我的所有 4 个视图”以上是关于Swift - 使用计时器检测用户不活动,然后在 4 分钟后显示警报以提示用户是不是仍然存在的主要内容,如果未能解决你的问题,请参考以下文章
通过Swift中的触摸检测应用程序何时处于活动状态或非活动状态[重复]
如何使用 UINavigationController 中的所有视图和导航控制器的导航控件检测用户活动?