应用进入前台后如何弹出视图?后台停留超X秒需重验PIN/密码
iOS 数字银行应用后台超时校验PIN功能实现方案
一、后台停留时长统计逻辑
你可以通过存储应用切后台的时间戳,切前台时计算时间差的方式实现时长统计,逻辑兼容AppDelegate+SceneDelegate双生命周期管理:
- 首先定义2个必要参数:
- 后台停留超时阈值
timeoutThreshold:可根据业务需求设置,金融类应用常用阈值为180~300秒 - 切后台时间戳存储键:建议存在
UserDefaults中,避免应用在后台被系统kill后数据丢失
- 后台停留超时阈值
- 在生命周期方法中补充时间记录与判断逻辑:
- 切后台时记录时间戳
针对iOS13及以上的SceneDelegate,在sceneDidEnterBackground方法中写入时间:
针对iOS12及以下仅使用AppDelegate的场景,在func sceneDidEnterBackground(_ scene: UIScene) { UserDefaults.standard.set(Date().timeIntervalSince1970, forKey: "kLastEnterBackgroundTimestamp") }applicationDidEnterBackground方法中添加相同的存储逻辑。
2. 切前台时计算后台停留时长
同样在双生命周期的切前台方法中做判断,SceneDelegate对应sceneWillEnterForeground:
同样在AppDelegate的func sceneWillEnterForeground(_ scene: UIScene) { // 未存储过切后台时间,直接跳过判断 guard let lastBackgroundTime = UserDefaults.standard.double(forKey: "kLastEnterBackgroundTimestamp") as? TimeInterval, lastBackgroundTime > 0 else { return } let currentTime = Date().timeIntervalSince1970 let backgroundDuration = currentTime - lastBackgroundTime // 停留时长超过阈值,触发PIN校验 if backgroundDuration > 300 { // 此处替换为你的超时阈值 showPinVerifyView() } }applicationWillEnterForeground方法中添加相同的判断逻辑,兼容低版本系统。 - 切后台时记录时间戳
二、PIN校验视图弹出逻辑
不要直接修改KeyWindow的根控制器,避免页面层级错乱,推荐获取当前顶层控制器来弹出校验页,同时禁止手势关闭避免绕过校验:
- 先添加获取顶层控制器的工具扩展:
extension UIApplication { static func getTopViewController() -> UIViewController? { guard let keyWindow = shared.connectedScenes .filter({$0.activationState == .foregroundActive}) .compactMap({$0 as? UIWindowScene}) .first?.windows .first(where: \.isKeyWindow), let rootVC = keyWindow.rootViewController else { return nil } var topVC = rootVC while let presentedVC = topVC.presentedViewController { topVC = presentedVC if let nav = topVC as? UINavigationController { topVC = nav.visibleViewController ?? topVC } else if let tab = topVC as? UITabBarController { topVC = tab.selectedViewController ?? topVC } } return topVC } }
- 实现校验页弹出方法:
func showPinVerifyView() { let pinVC = YourPinVerifyViewController() // 替换为你自己实现的PIN输入控制器 pinVC.modalPresentationStyle = .fullScreen pinVC.isModalInPresentation = true // 禁止手势下滑关闭,必须校验通过才能进入应用 guard let topVC = UIApplication.getTopViewController() else { return } // 避免重复弹出校验页 if !(topVC is YourPinVerifyViewController) { topVC.present(pinVC, animated: false) } }
注意事项
- 若应用在后台被系统强制销毁,重新启动时可直接触发PIN校验,无需走时长判断逻辑
- PIN校验完成前需拦截所有底层页面的交互操作,避免敏感信息泄露
- 超时阈值建议提供用户自定义入口,兼顾安全性和使用体验
内容的提问来源于stack exchange,提问作者Abigail Aryaputra
相关产品推荐
相关产品推荐

