mcpField
C
capacitor-uiscene-migrator

capacitor-uiscene-migrator

github.com/ionic-team开发28210 次安装13 周前更新
代码仓库

关于 capacitor-uiscene-migrator

用于将 Capacitor 8.4 iOS 应用迁移到 8.5 UIScene 生命周期的引导技能,也可审查插件兼容性。它先审计再修改、征求开发者对关键决策的意见,以合并方式保留现有代码,并将符合条件的项目交给 CLI 迁移工具处理。

主要功能

  1. 01判定迁移状态及部分完成状态
  2. 02审查 iOS 生命周期代码和插件
  3. 03将符合条件的项目交给 npx cap migrate
  4. 04合并现有文件而非覆盖
  5. 05提供插件兼容性指导

适用场景

  1. 01迁移经过定制的 Capacitor iOS 应用
  2. 02继续处理 CLI 跳过的项目
  3. 03审查插件的 UIScene 兼容性
  4. 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.md
plugin-repo-audit.md
scene-delegate-template.md
surgical-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/cli 8.5+
  • 如果开发者希望验证构建,则需安装 Xcode

8.5 中的变化(审查所依据的事实)

这些内容决定了哪些会出问题、哪些不会。不要弱化表述。

  • 场景接入为可选项。没有 UIApplicationSceneManifest 的应用会继续使用 AppDelegate 路径,该路径在 8.5 核心中仍然有效。即使是传统应用,iOS 也会发送 UIScene.* 通知(兼容性场景),因此桥接的 JS resume/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 迁移工具使用的相同三项信号:

  1. Info.plist 包含 UIApplicationSceneManifest
  2. 应用目标目录中存在 SceneDelegate.swift 文件(pbxproj 注册是另一项工作,在第 7 阶段处理)
  3. 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:决策点

至少询问:

  1. 旧版 URL 处理程序:保留还是移除 application(_:open:options:) / application(_:continue:)(位于 AppDelegate.swift 中)?在 scenes 下,它们会成为死代码。保留无妨;移除则更简洁。如果方法体包含自定义逻辑,无论如何都必须将其移到 SceneDelegate。在符合条件的路线上,等 CLI 运行后再应用答案。
  2. 自定义 application(_:open:) 方法体:手动迁移(由开发者移动逻辑),还是由该技能将其与代理转发器一并移到 scene(_:openURLContexts:) 中?提问前先展示方法体。如果根据审计测试,方法体仅包含转发逻辑,则跳过此问题。
  3. 已有的 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 插件迁移到 Capacitor
  • capacitor-plugin-generator:新的 Capacitor 插件脚手架

参考资料

文件用途
references/scene-delegate-template.md8.5 SceneDelegate 模板和自定义子类变体
references/audit-patterns.md包含命令的精确扫描模式
references/surgical-merges.md部分项目和手工搭建项目的合并方案
references/plugin-repo-audit.md插件作者分支:审计和兼容性规则

评论

支持 Markdown