关于 capacitor-uiscene-migrator
用于将 Capacitor 8.4 iOS 应用迁移到 8.5 UIScene 生命周期的引导技能,也可审查插件兼容性。它先审计再修改、征求开发者对关键决策的意见,以合并方式保留现有代码,并将符合条件的项目交给 CLI 迁移工具处理。
主要功能
- 01判定迁移状态及部分完成状态
- 02审查 iOS 生命周期代码和插件
- 03将符合条件的项目交给 npx cap migrate
- 04合并现有文件而非覆盖
- 05提供插件兼容性指导
适用场景
- 01迁移经过定制的 Capacitor iOS 应用
- 02继续处理 CLI 跳过的项目
- 03审查插件的 UIScene 兼容性
- 04排查 UIScene 生命周期警告
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ ionic-team/ capacitor-skills --skill capacitor-uiscene-migrator安装后在 Claude Code 中输入/capacitor-uiscene-migrator确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/audit-patterns.mdplugin-repo-audit.mdscene-delegate-template.mdsurgical-merges.md详细介绍
Capacitor UIScene 迁移器
指导将 Capacitor 8.4 → 8.5 iOS 应用迁移到 UIScene 生命周期。
CLI 迁移器(npx cap migrate)适用于仍符合 Capacitor 模板的项目;此技能则适用于其他情况。它会在编辑前进行审查,在需要判断时询问开发者,合并到现有文件而不是替换文件,并在项目结构允许时将机械性工作交给 CLI。
权威迁移参考是 8.4 → 8.5 迁移指南。 凡是需要开发者手动完成的步骤,都应链接到该指南。
何时使用此技能
- 将 Capacitor 8.x iOS 应用迁移到 UIScene 生命周期
npx cap migrate报告了部分迁移状态并跳过某些内容的项目- 使用手动编写的
SceneDelegate.swift或自定义AppDelegate.swift(深层链接路由、第三方 SDK 转发)的应用 - 审查 Capacitor 插件仓库的 UIScene 兼容性
- 诊断 Capacitor 应用中的 Xcode“CLIENT OF UIKIT REQUIRES UPDATE: This process does not adopt UIScene lifecycle”警告
何时不应使用此技能
- Cordova 到 Capacitor 的插件迁移 →
cordova-plugin-migrator - 生成新的 Capacitor 插件 →
capacitor-plugin-generator - Capacitor 9 或更高版本的迁移(此技能仅适用于 8.4 → 8.5)
- Android 生命周期相关工作(UIScene 仅适用于 iOS)
- 与场景生命周期无关的常规 Capacitor 调试
先决条件
- 一个带有
ios/平台或 iOS 源码的 Capacitor 8.x 项目(应用或插件) - 可用于移交给
npx cap migrate的@capacitor/cli8.5+ - 如果开发者希望验证构建,则需安装 Xcode
8.5 中的变化(审查所依据的事实)
这些内容决定了哪些会出问题、哪些不会。不要弱化表述。
- 场景接入为可选项。没有
UIApplicationSceneManifest的应用会继续使用 AppDelegate 路径,该路径在 8.5 核心中仍然有效。即使是传统应用,iOS 也会发送UIScene.*通知(兼容性场景),因此桥接的 JSresume/pause事件在两种模式下都会触发。 - 场景清单存在后,iOS 将不再调用
application(_:open:options:)、application(_:continue:)和四个 AppDelegate 前台/后台方法(applicationDidBecomeActive、applicationWillResignActive、applicationDidEnterBackground、applicationWillEnterForeground)。这些方法中的自定义代码会静默停止运行。UIApplication通知仍会触发;didFinishLaunching、applicationWillTerminate、推送令牌注册以及远程通知回调仍由 AppDelegate 处理。 SceneDelegateProxy会以相同的载荷结构重新发布旧版.capacitorOpenURL、.capacitorOpenUniversalLink和CDVPluginHandleOpenURL通知,因此现有观察者仍可正常工作。冷启动 URL 会在桥接视图出现后传递,因此appUrlOpen和getLaunchUrl()在冷启动时都能正常工作。- 新的
.capacitorSceneWillConnect、.capacitorSceneOpenURL和.capacitorSceneOpenUniversalLink通知会将UIScene作为对象传递。这些通知仅在 8.5+ 上发布;同时支持 8.4 的插件必须继续使用旧名称。 TmpViewController和CapacitorBridge.tmpWindow已移除。在 8.5 中,任何引用都会导致构建错误。- 8.5 模板会在
scene(_:willConnectTo:)中通过代码创建窗口;Main.storyboard不再提供根视图控制器。自定义CAPBridgeViewController子类会在 SceneDelegate 中实例化,而不是在 storyboard 中设置。
Agent 行为
- 先审查,再报告,最后编辑。在开发者查看发现并确认之前,绝不修改文件。
- 绝不覆盖现有的
SceneDelegate.swift、AppDelegate.swift或Info.plist结构。按照 references/surgical-merges.md 进行精准合并。 - 优先使用 CLI。如果项目符合条件(第 3 阶段),运行
npx cap migrate,不要手动编辑文件。 - 在第 6 阶段的决策点询问,不要自行假设。若可用,请使用
AskUserQuestion;否则用纯文本提问并等待回复。 - 不要提交、暂存或推送。将版本控制工作留给开发者。
- 对于插件仓库,绝不改动
Info.plist、AppDelegate.swift或项目文件。插件分支仅用于审查和提供建议。
流程
第 1 阶段:检测仓库类型
首先判断是应用还是插件。
- 应用:包含
ios/App/App.xcodeproj(或包含ios/平台目录的capacitor.config.*)。 - 插件:包含依赖 Capacitor 的
Package.swift或.podspec,在ios/Sources或ios/Plugin中有CAPPlugin/CapacitorPlugin子类,并且没有App/App.xcodeproj。
插件仓库 → 跳转到第 10 阶段 (references/plugin-repo-audit.md)。
第 2 阶段:检测包管理器和版本
- Pods 与 SPM:
ios/App/Podfile→ CocoaPods;Package.swift或 Xcode 项目中的 SPM 引用 → SPM。这会影响npx cap sync ios的行为,但不会影响 SceneDelegate 内容:8.5 模板对两者使用相同的 SceneDelegate。 - 检查
package.json中的@capacitor/ios版本。如果低于 8.5,迁移时需要更新依赖;CLI 迁移工具会处理此事,也可以按照指南手动更新。
第 3 阶段:判定项目状态
读取 CLI 迁移工具使用的相同三项信号:
Info.plist包含UIApplicationSceneManifest- 应用目标目录中存在
SceneDelegate.swift文件(pbxproj 注册是另一项工作,在第 7 阶段处理) AppDelegate.swift包含UISceneConfiguration(name:
| 存在的信号 | 状态 | 路径 |
|---|---|---|
| 3 项中有 0 项 | 符合条件 | 第 4-6 阶段,然后第 7a 阶段:交由 npx cap migrate 处理 |
| 3 项中有 3 项 | 已迁移 | 仅审查(第 4 阶段),然后验证(第 9 阶段) |
| 3 项中有 1-2 项 | 部分完成 | 第 4-6 阶段,然后第 7b 阶段:精准合并 |
所有路径都会在执行或更改任何内容之前先进行审查;各路径的区别仅在于由谁应用更改。
CLI 按设计会对部分完成的状态发出警告并跳过。部分完成的状态正是此技能自行编辑的情况。
第 4 阶段:审查代码库
按照 references/audit-patterns.md 中的说明,扫描应用的 iOS 源码和已安装的插件(node_modules/@capacitor*,以及任何本地插件路径)。收集以下发现:
- 使用
UIApplication.shared.applicationState的情况 ApplicationDelegateProxy转发器之外的自定义application(_:open:)/application(_:continue:)方法体- AppDelegate 生命周期方法中的自定义代码
- 现有的
SceneDelegate.swift实现及其内容 - 对
tmpWindow/TmpViewController的引用(在 8.5 中会导致构建错误) - 现有或部分配置的
UIApplicationSceneManifest条目 .capacitorOpenURL/.capacitorOpenUniversalLink观察者(仅供参考:这些仍可正常工作)
第 5 阶段:展示发现并确认
动手修改之前,报告每项发现及其文件和行号。 分组为:阻碍构建(tmpWindow/TmpViewController)、需要决策(自定义委托方法体、现有 SceneDelegate)、仅供参考(观察者、开发者不拥有的插件中的 applicationState)。 请开发者确认是否继续。
阶段 6:决策点
至少询问:
- 旧版 URL 处理程序:保留还是移除
application(_:open:options:)/application(_:continue:)(位于AppDelegate.swift中)?在 scenes 下,它们会成为死代码。保留无妨;移除则更简洁。如果方法体包含自定义逻辑,无论如何都必须将其移到 SceneDelegate。在符合条件的路线上,等 CLI 运行后再应用答案。 - 自定义
application(_:open:)方法体:手动迁移(由开发者移动逻辑),还是由该技能将其与代理转发器一并移到scene(_:openURLContexts:)中?提问前先展示方法体。如果根据审计测试,方法体仅包含转发逻辑,则跳过此问题。 - 已有的 SceneDelegate:以差异形式确认每项拟议的插入(缺少的转发器、窗口设置)后再应用。
阶段 7a:符合条件 → CLI 交接
先验证解析到的 CLI:如果缺少 node_modules,运行 npm install,然后运行 npx cap --version;UIScene 迁移器需要 8.5 或更高版本。然后运行 npx cap migrate 并解读其输出。它会写入 SceneDelegate.swift、修改 Info.plist 和 AppDelegate.swift、在 project.pbxproj 中注册该文件、针对阶段 4 的扫描模式发出警告,并链接迁移指南。逐项确认日志行;如果 CLI 跳过了某一步(文件已存在、部分状态发生竞争),则仅针对该步骤转到阶段 7b。
阶段 7b:部分迁移或手动迁移 → 精准合并
根据 references/surgical-merges.md,仅应用缺少的部分:
- 缺少清单 → 将
UIApplicationSceneManifest合并到Info.plist中,同时保留现有键 - 缺少
configurationForConnecting→ 插入到现有AppDelegate.swift中,位于类的右花括号之前,不替换任何内容 - 缺少或不完整的
SceneDelegate.swift→ 根据 references/scene-delegate-template.md 创建,或将缺少的SceneDelegateProxy.shared转发器添加到现有文件中,同时保留所有自定义逻辑 - 新文件 → 在
project.pbxproj中注册(通过 IDE 添加文件时,Xcode 会自动完成;否则请遵循参考文档)
阶段 8:同步和构建
运行 npx cap sync ios。如果可以使用 Xcode,则构建应用目标并指出任何错误(最常见的是残留的 tmpWindow 引用)。
阶段 9:验证清单
引导开发者逐项检查,并链接指南以了解详情:
- 应用启动后显示 Web 视图
- 将应用切换到后台再切回前台:JS
resume/pause会触发(现在它们的作用范围仅限于应用的 scene) - 自定义 URL scheme:冷启动和热启动打开都能传递 URL(
appUrlOpen监听器和App.getLaunchUrl()) - 如果应用使用通用链接,也要验证(需要关联域名)
阶段 10:插件仓库分支
无需修改应用级文件。根据 references/plugin-repo-audit.md 审计插件的 Swift 代码,并报告:在 scenes 下会失效的生命周期假设、8.5 中移除的 API,以及使用单个插件版本同时支持 8.4 和 8.5 的兼容性规则。仅在开发者提出要求时才应用代码更改,且仅限插件自身的源文件。
最佳实践
应做
- 应用更改前展示差异
- 将每项发现都关联到具体文件和行号
- 编辑后重新运行阶段 3 的分类,以确认项目已完全迁移
- 告知插件作者:在支持 8.4 期间,应保留旧版通知名称
不应做
- 绝不覆盖用户代码
- 不要重写
node_modules中的第三方插件代码(应报告此问题;修复应由上游完成) - 不要在符合条件的项目中手动编辑,以重复 CLI 已完成的工作
- 不要在没有关联域名可供测试时承诺通用链接的行为
错误处理
npx cap migrate警告“partial state” → 这是预期行为;本技能为此提供了 Phase 7b。未经询问,不要重置项目。- 编辑
project.pbxproj失败或项目无法再打开 → 撤销对 pbxproj 的更改,并改用 Xcode 注册文件。 - 构建因
tmpWindow/TmpViewController失败 → 必须删除这些引用;8.5 没有替代项(桥接层的viewController是呈现锚点)。 - 存在
SceneDelegate,但应用显示黑屏 → 该代理既没有创建窗口,也没有让 storyboard 创建窗口;添加模板中的窗口设置。
相关技能
cordova-plugin-migrator:将 Cordova 插件迁移到 Capacitorcapacitor-plugin-generator:新的 Capacitor 插件脚手架
参考资料
| 文件 | 用途 |
|---|---|
| references/scene-delegate-template.md | 8.5 SceneDelegate 模板和自定义子类变体 |
| references/audit-patterns.md | 包含命令的精确扫描模式 |
| references/surgical-merges.md | 部分项目和手工搭建项目的合并方案 |
| references/plugin-repo-audit.md | 插件作者分支:审计和兼容性规则 |