如果我锁定屏幕或 iPhone 开始休眠,但我从未退出应用程序,那么该应用程序是不是仍被视为后台运行?
Posted
技术标签:
【中文标题】如果我锁定屏幕或 iPhone 开始休眠,但我从未退出应用程序,那么该应用程序是不是仍被视为后台运行?【英文标题】:If I lock the screen or the iPhone starts to sleep, but I never tab out of the app, is the app still considered backgrounded?如果我锁定屏幕或 iPhone 开始休眠,但我从未退出应用程序,那么该应用程序是否仍被视为后台运行? 【发布时间】:2021-07-22 21:24:19 【问题描述】:如果我从未真正将当前应用程序留给另一个应用程序 - 并且屏幕关闭或设备被锁定。
applicationDidEnterBackground
、applicationWillEnterForeground
、etc
等生命周期方法还会被调用吗?
基本上我的问题是:就生命周期方法而言,屏幕锁定/设备睡眠的行为是否与切换到另一个应用程序的行为相同。
【问题讨论】:
【参考方案1】:是的,除了在现代应用程序中,所有这些内容都已移至场景委托。如果屏幕被锁定并且你在最前面,你会得到:
sceneWillResignActive(_:)
sceneDidEnterBackground(_:)
然后当屏幕解锁时你会得到:
sceneWillEnterForeground(_:)
sceneDidBecomeActive(_:)
【讨论】:
作为最后的健全性检查,这与我正常切换一个应用程序(或进入主屏幕)时得到的行为完全相同,对吧? 是的,没有区别。 感谢您的澄清!它真的很有帮助,尤其是作为一个初学者!我很感激!【参考方案2】:FWIW,如果您以后想自己诊断这类应用生命周期事件,可以使用 Logger
或 os_log
在您的 macOS 控制台应用上观看这些 ios 事件。
注意,我不依赖 Xcode 调试器,因为将应用程序附加到调试器会改变应用程序的生命周期。我明确不通过 Xcode 调试器运行应用程序,而是直接在之前在我的 Mac 上退出 Xcode 的设备上运行它。
简而言之,是的,只需关闭手机(但不完全关机)即可让您的应用进入后台模式。这是我启动应用程序的日志,然后点击 iPhone 侧面的电源按钮将其关闭:
此行为与我刚刚向上滑动返回主屏幕的以下日志非常相似:
但如果您在应用程序运行时完全关闭设备,您会看到它sceneWillResignActive
,但不出所料,它永远不会到达sceneDidEnterBackground
:
如果您在应用程序处于活动状态时强制退出:
有关记录应用程序并从 macOS 控制台观察这些记录的更多信息,请参阅 WWDC 2020 的 Explore logging in Swift 或 WWDC 2016 的 Unified Logging and Activity Tracing 了解这些记录选项。
FWIW,这是我的日志记录:
// AppDelegate.swift
import UIKit
import os
private let logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "AppDelegate")
@main
class AppDelegate: UIResponder, UIApplicationDelegate
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool
logger.debug(#function)
...
return true
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration
logger.debug(#function)
...
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>)
logger.debug(#function)
...
还有:
// SceneDelegate.swift
import UIKit
import os
private let logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "SceneDelegate")
class SceneDelegate: UIResponder, UIWindowSceneDelegate
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions)
logger.debug(#function)
...
guard let _ = (scene as? UIWindowScene) else return
func sceneDidDisconnect(_ scene: UIScene)
logger.debug(#function)
...
func sceneDidBecomeActive(_ scene: UIScene)
logger.debug(#function)
...
func sceneWillResignActive(_ scene: UIScene)
logger.debug(#function)
...
func sceneWillEnterForeground(_ scene: UIScene)
logger.debug(#function)
...
func sceneDidEnterBackground(_ scene: UIScene)
logger.debug(#function)
...
如果你使用os_log
而不是Logger
(后者在macOS 11和iOS 14中引入),过程非常相似。您会以同样的方式在控制台中看到os_log
消息。
【讨论】:
感谢您抽出宝贵时间回答!此类帖子对像我这样的 Swift 新手程序员非常有帮助。以上是关于如果我锁定屏幕或 iPhone 开始休眠,但我从未退出应用程序,那么该应用程序是不是仍被视为后台运行?的主要内容,如果未能解决你的问题,请参考以下文章
应用程序暂停时如何在 iPhone 上获取屏幕锁定/解锁事件?