You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

XCode 12 如何为SwiftUI App生命周期应用添加SceneDelegate

核心结论

纯SwiftUI App生命周期的应用不需要直接在App主结构内声明、挂载SceneDelegate类——系统会自动为SwiftUI的Scene容器绑定默认的场景管理逻辑,你自行编写的裸SceneDelegate如果没有合法的系统绑定入口,根本不会被触发。
实际开发中可根据需求选择对应实现方案:

方案1:优先用SwiftUI原生能力,替代90%的SceneDelegate常用场景

绝大多数你想用SceneDelegate实现的需求(比如监听前后台切换、应用状态变化),都可以通过SwiftUI原生的scenePhase环境值实现,不需要引入任何UIKit的Delegate类。
直接在你现有代码基础上修改即可:

import SwiftUI

@main
struct SampleApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    // 新增:注入系统的场景阶段状态
    @Environment(\.scenePhase) private var scenePhase

    var body: some Scene {
        WindowGroup {
            HomeView()
        }
        // 监听场景状态变化,和原SceneDelegate的常用回调一一对应
        .onChange(of: scenePhase) { phase in
            switch phase {
            case .active:
                // 对应UIWindowSceneDelegate的sceneDidBecomeActive(_:)
                break
            case .inactive:
                // 对应UIWindowSceneDelegate的sceneWillResignActive(_:)
                break
            case .background:
                // 对应UIWindowSceneDelegate的sceneDidEnterBackground(_:)
                NetworkManager.shared.stopMonitoring()
            @unknown default:
                break
            }
        }
    }
}

这种方式是苹果官方推荐的实现,没有额外的UIKit依赖,生命周期逻辑和SwiftUI的渲染流程完全对齐。

方案2:必须使用UIKit SceneDelegate时的合法绑定方式

如果有历史代码迁移、需要调用SceneDelegate专属API(比如自定义URL跳转处理、多窗口状态恢复、场景级配置等),不能直接在App结构里加类,需要通过已经接入的AppDelegate完成绑定:

  1. 编写遵守UIWindowSceneDelegate协议的SceneDelegate类:
final class SceneDelegate: NSObject, UIWindowSceneDelegate {
    // 场景连接回调
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        guard let windowScene = scene as? UIWindowScene else { return }
        // 在这里放置原UIKit项目中的场景初始化、配置逻辑
    }

    // 场景级URL跳转处理
    func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
        // 处理外部唤起的URL逻辑
    }
}
  1. 在已有的AppDelegate中实现系统回调,告诉系统要使用的SceneDelegate配置:
final class AppDelegate: NSObject, UIApplicationDelegate {
    // 新增:为系统指定场景创建时使用的Delegate
    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        let sceneConfig = UISceneConfiguration(name: "Default Config", sessionRole: connectingSceneSession.role)
        sceneConfig.delegateClass = SceneDelegate.self
        return sceneConfig
    }

    // 保留你原有的AppDelegate逻辑
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        NetworkManager.shared.startMonitoring()
        return true
    }

    func applicationWillTerminate(_ application: UIApplication) {
        NetworkManager.shared.stopMonitoring()
    }
}

注意事项

  • 绑定后不要在SceneDelegate中手动创建UIWindow实例,否则会和SwiftUIWindowGroup的默认窗口管理逻辑冲突,出现窗口丢失、渲染异常的问题。
  • 这种绑定方式兼容iPadOS多窗口、多场景的需求,系统会为每一个独立创建的场景实例化你指定的SceneDelegate对象。
  • 非必要不使用该方案,优先用SwiftUI原生的scenePhase能力,减少生命周期逻辑的割裂感。

内容的提问来源于stack exchange,提问作者Rijo Samuel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.22 22:15:03