如果我锁定屏幕或 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 【问题描述】:

如果我从未真正将当前应用程序留给另一个应用程序 - 并且屏幕关闭或设备被锁定。

applicationDidEnterBackgroundapplicationWillEnterForegroundetc 等生命周期方法还会被调用吗?

基本上我的问题是:就生命周期方法而言,屏幕锁定/设备睡眠的行为是否与切换到另一个应用程序的行为相同。

【问题讨论】:

【参考方案1】:

是的,除了在现代应用程序中,所有这些内容都已移至场景委托。如果屏幕被锁定并且你在最前面,你会得到:

sceneWillResignActive(_:) sceneDidEnterBackground(_:)

然后当屏幕解锁时你会得到:

sceneWillEnterForeground(_:) sceneDidBecomeActive(_:)

【讨论】:

作为最后的健全性检查,这与我正常切换一个应用程序(或进入主屏幕)时得到的行为完全相同,对吧? 是的,没有区别。 感谢您的澄清!它真的很有帮助,尤其是作为一个初学者!我很感激!【参考方案2】:

FWIW,如果您以后想自己诊断这类应用生命周期事件,可以使用 Loggeros_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 的锁定屏幕中开始播放音乐

应用程序暂停时如何在 iPhone 上获取屏幕锁定/解锁事件?

如何使用损坏的电源按钮锁定iPhone 或 iPad?

我可以以编程方式锁定我的iPhone屏幕吗?

iPhone iOS如何在应用程序从后台恢复时添加密码/密码锁定屏幕?

如何检测是不是启用了屏幕自动锁定