iOS17 Swift:如何区分App锁屏进入后台与解锁进入后台?
区分iOS App进入后台的两种场景:锁屏 vs Home键/上滑返回
问题场景
- 场景1:打开App时按下锁屏键,设备锁定,App进入后台
- 场景2:打开App时按下Home键或上滑返回,设备保持解锁,App进入后台
两种场景下App均会进入后台,但仅通过applicationWillResignActive、applicationDidBecomeActive、applicationDidEnterBackground这三个生命周期方法无法区分触发原因——两种场景都会触发全部三个方法,导致UserDefaults中的标记全部为true,无法判断是锁屏还是Home操作导致的后台切换。
解决方案
核心思路是利用iOS的保护数据可用性来区分:锁屏会触发App的保护数据变为不可用,而Home键/上滑返回操作不会影响保护数据的可用性。
方法1:在applicationWillResignActive中直接判断
修改AppDelegate.swift中的applicationWillResignActive方法,通过UIApplication.isProtectedDataAvailable判断当前状态:
func applicationWillResignActive(_ application: UIApplication) { // 锁屏时保护数据不可用,Home操作时仍可用 let isLockTriggered = !UIApplication.shared.isProtectedDataAvailable if isLockTriggered { print("App进入后台:锁屏触发") // 执行锁屏场景的逻辑 } else { print("App进入后台:Home键/上滑返回触发") // 执行Home操作场景的逻辑 } }
方法2:监听系统通知(更可靠)
通过监听UIApplication.protectedDataWillBecomeUnavailableNotification和UIApplication.protectedDataDidBecomeAvailableNotification通知,精准捕获锁屏/解锁事件:
- 在
application(_:didFinishLaunchingWithOptions:)中添加通知监听:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // 监听保护数据不可用通知(锁屏触发) NotificationCenter.default.addObserver(self, selector: #selector(handleLockScreen), name: UIApplication.protectedDataWillBecomeUnavailableNotification, object: nil) // 监听保护数据可用通知(解锁触发) NotificationCenter.default.addObserver(self, selector: #selector(handleUnlockScreen), name: UIApplication.protectedDataDidBecomeAvailableNotification, object: nil) return true }
- 实现对应的处理方法:
@objc private func handleLockScreen() { print("App进入后台:锁屏触发") // 处理锁屏场景逻辑 } @objc private func handleUnlockScreen() { print("App回到前台:设备解锁") // 处理解锁场景逻辑 }
- (可选,iOS 9+系统自动处理,显式移除更规范)在AppDelegate销毁时移除通知监听:
deinit { NotificationCenter.default.removeObserver(self) }
原方案失效原因
两种场景都会完整触发以下生命周期流程:
- 锁屏:
applicationWillResignActive→applicationDidEnterBackground;解锁时触发applicationDidBecomeActive - Home操作:
applicationWillResignActive→applicationDidEnterBackground;切回App时触发applicationDidBecomeActive
因此仅通过标记这三个方法的执行状态,无法区分触发源。
内容的提问来源于stack exchange,提问作者Syed Muhammad Mohsin Ali Naqvi
相关产品推荐
相关产品推荐

