一、iOS 27 的变化与坑点
这些年 Apple 一直在“劝”咱们用 UIScene 的生命周期管理模式。虽然之前出了很多版本都在报 warning,但咱们很多项目为了图省事,一直赖着旧的 AppDelegate 模式跑,反正程序运行起来也没啥不对。
但到了 iOS 27(预计 2026 年 9 月发布)情况就完全不同了。
从 iOS 27 的 SDK 开始,如果你还在死守着 UIApplicationDelegate 这种老旧的生命周期管理方式,你的 App 将会直接无法启动。这不是报个警告那么简单,而是直接在运行时报错,程序根本跑不起来。
这里有个误解,很多人觉得 AppDelegate 被废弃了。其实没那么夸张,AppDelegate 依然负责应用层面的进程生命周期,变的是 UI 相关的责任划分。简单说,现在 UI 的窗口管理、生命周期、多场景、状态恢复以及 URL 处理,全都得归 UISceneDelegate 管。
两者的分工现在非常明确:
AppDelegate | |
SceneDelegate |
这种设计早在 iOS 13 就引入了,只不过现在 Apple 打算直接把它变成强制项。
二、如何判断你的 App 会不会中招
这个坑最坑的地方在于:你的代码可能依然能通过编译,App 也能正常安装到手机上,但只要你用 iOS 27 的 SDK 去构建,运行的时候就会直接挂掉。
如果你的项目存在以下任一情况,那么在 iOS 27 上一定会出问题:
• 在 Info.plist中没配置UIApplicationSceneManifest。• 在 AppDelegate中没有相应的Scene配置。
三、迁移实战指南
为了平滑过渡,咱们需要分场景来看待这个迁移工作。
1、UIKit 项目迁移
如果你做的是原生 UIKit 开发,迁移逻辑主要分为三步:
第一,配置Scene Manifest你得在 Info.plist 里加上 UIApplicationSceneManifest 配置。虽然现在大部分 App 只需要单一窗口,但 Apple 强制要求你必须显式声明这个生命周期模式。
第二,搬迁生命周期事件很多传统的 AppDelegate 方法现在都要挪到 SceneDelegate 里去。比如:
• applicationDidBecomeActivesceneDidBecomeActive• applicationDidEnterBackgroundsceneDidEnterBackground
这里是重灾区。像 Deep Links、Universal Links、Handoff 这些功能,现在都会通过 SceneDelegate 传进来。如果逻辑没写对,代码虽然不报错,但功能会直接失效。
第三,修正 API 调用之前咱们喜欢用 UIApplication.shared.windows 或者 UIApplication.shared.keyWindow 来拿当前窗口,这种写法在 Scene 模式下已经不靠谱了。现在得通过 UIWindowScene 来获取正确的窗口实例。
2、Flutter 项目迁移
对于 Flutter 开发者来说,好消息是 Flutter 官方已经替咱们分担了不少压力。
从 Flutter 3.41 版本开始,在构建时会自动把符合条件的项目迁移到 UIScene 模型。但有一个非常常见的坑:如果你的原生部分写了自定义的 AppDelegate(在企业级项目中非常普遍),你得手动把插件注册的逻辑移到 didInitializeImplicitFlutterEngine 这个回调里。
另外,任何依赖 FlutterViewController 进行启动阶段操作的 Method Channels 或 Platform Views,也得重新审视一下。
这里附上
Flutter官方的UIScene适配文档: https://docs.flutter.dev/release/breaking-changes/uiscenedelegate
四、最后聊聊建议
虽然现在离 iOS 27 强制要求还不远,但真等那时候再来搞,万一遇到复杂的 Deep Links 或者 Push Notifications 回调问题,肯定会手忙脚乱。
我建议的节奏是:
1. 先给现有的项目做个审计,看看是不是还在单纯依赖 AppDelegate。2. 抽个时间开个分支专门搞迁移。 3. 重点测试 Universal Links、Push、Background Refresh以及OAuth登录等涉及到复杂生命周期的功能。
这事儿比起代码实现,其实更多的精力应该花在回归测试上。早点把这部分技术债清掉,比等最后期限临近了再去硬刚要稳妥得多。
夜雨聆风