AI 辅助的 iOS 到 KMP 代码迁移实践

初稿于 2026 年 1 月发表于公司内网,上站前做了脱敏改写

团队在推进底部 Tab 功能的 KMP 化——KMP(Kotlin Multiplatform)是把业务逻辑用 Kotlin 写一遍、双端共用的跨平台方案,存量的 Objective-C 代码需要转写成 Kotlin。手工逐行翻译既耗时又容易出错,我们借这个机会验证了一件事:AI 辅助的代码迁移,能做到什么程度。

这次实践要回答三个问题:AI 转写的采纳率能到多少;哪些类型的代码适合交给 AI 转写;人和 AI 各自该干什么。

工具前提

转写工作跑在团队的 AI 编码启动器上。它本身不是模型,是一层工程化封装:在当前代码仓库里一键接入 CLI Coding Agent(Claude Code 这类),同时把团队知识库挂载进工作目录。具体做了四件事:

  • 知识库挂载:把工程规则文档和平台接口文档软链到工程目录,Agent 对话时自动带上工程规范。
  • 一键启动:自动检测并启动 CLI Agent,不需要每个人手动配环境。
  • 按平台过滤:文档可以按 iOS / Android / KMP 过滤,减少无关文档体积,提高检索命中率。
  • 缓存加速:依赖环境装在缓存目录,没有变化就跳过安装。

这层封装决定了后面所有做法的可行性:转写规则、平台接口文档、进度追踪都以文件形式放在 Agent 随手可及的位置,而不是靠人在对话里反复粘贴。

转写前的准备

准备阶段的投入直接决定转写质量的上限。三件事:

模块化拆分。先把要迁移的代码内聚成独立的 Objective-C 类,再逐一转写。让 AI 每次聚焦一个小模块,比一次投喂海量代码的准确率高得多。

基建文档先行。把 KMP 侧已有的能力——网络请求、数据模型、工具类、平台接口——以文档形式放进知识库。AI 能复用这些已有模式,而不是自己重新发明一套。后面的迭代记录会说明,这一条没做好是第一轮返工的主要原因。

纯逻辑代码优先。业务逻辑、数据处理这类与平台耦合少的代码最容易转成 Kotlin,复用效果也最好。UI 代码先放着。

转写流程

单个模块的转写流程固定下来是这样:

OC 源文件(.h + .m 配对输入)
  → 加载知识库(自动拉取 KMP 规范文档与目标仓库)
  → 强制学习平台接口文档
  → 按目标范式执行翻译(StateHolder / ViewModel / 普通类)
  → 产出 Kotlin 代码,更新进度文件

两个设计值得说明。

一是强制使用 SPI。KMP 代码调用平台能力(KV 存储、日志、埋点、AB 实验)必须走统一的 SPI 接口(Service Provider Interface,平台能力的抽象层),不允许直接触碰平台 API。我们把「先读 SPI 文档」写成流程里的强制步骤,跳过这一步的转写结果几乎必然要返工。

二是进度文件。用一个 Markdown 文件记录每个模块的翻译和审查状态。多轮会话、多人协作时,Agent 和人看同一份进度,不依赖谁的记忆。

迭代审查

转写完成不等于结束,进入「自动审查 + 人工审查 → AI 修复」的循环:先跑专用的审查命令让 AI 对照编码规范自查,再由开发者人工审查标注问题,问题反馈给 AI 修复,然后再审,直到通过。

以第一个完成迁移的核心类(底部 Tab 红点逻辑的管理类)为例,四轮迭代各自暴露的问题:

轮次典型问题处理方式
第一轮不知道 KMP 侧已有文件读写、日志、埋点能力,自己实现了一遍接口把能力文档补进知识库
第二轮逻辑顺序颠倒、引用判断写错按人工审查意见让 AI 修复
第三轮配置读写没有使用专门的封装类引导使用规范组件替代桥接调用
第四轮没有使用现成的时间工具组件、用了 !! 非空断言按编码规范修正

四轮下来,这个类的绝大多数转写结果被直接采纳——以排除空行和注释后的有效代码行计,被人工替换或删除的只是零星几处。四轮迭代的问题也有清晰的层次:第一轮是知识缺口,第二轮是逻辑错误,第三、四轮已经收敛到编码规范。知识库每补一块,下一个模块就少踩一类坑。

工具链的演进

转写工具链不是一次设计出来的,实践过程中改了五轮,按时间顺序:

  1. 把通用命令改成迁移专用命令,补上审查命令。
  2. 引入进度追踪文件,把知识库拉取改成自动执行。
  3. 强制 SPI 学习步骤,支持 .h.m 配对输入,精炼翻译指南。
  4. 补环境配置:输出 token 上限的环境变量、本地路径与相对路径引用。
  5. 完善核心规则文档,规范任务描述格式。

其中翻译命令最终稳定在 274 行——包含翻译规则和目标代码模板。这个规模是试出来的:太短则约束不住输出风格,太长则重要规则被淹没。

边界

这次实践对「AI 能转什么」给出了一个可操作的判断标准:

适合 AI 转写 = 依赖干净 + 不碰 UI

适合的:纯业务逻辑、数据处理、模型封装、工具类。不适合的:UI 组件、平台强相关的 API 调用、复杂状态管理。

优势是明确的。熟悉的 Objective-C 代码转成 Kotlin 后,省掉了逐行查文档的时间;AI 产出的代码会自然用上 Kotlin 的扩展函数、数据类和 lambda,对刚接触 Kotlin 的 iOS 开发者反而是学习材料。

限制同样明确。UI 层强依赖 UIKit 的框架和生命周期,不解耦就没法转,解耦本身是人的工作;跨文件的前后依赖,AI 的理解仍然需要文档辅助;转写产物必须经过完整测试,这部分成本省不掉。

可复用的做法

如果要在别的模块或别的团队复现这套流程,四条经验按重要性排序:

  1. 纯逻辑优先。让 AI 负责逻辑和数据结构的转换,把平台差异留给人。
  2. UI 先解耦再谈迁移。没有解耦的 UI 代码不要投给 AI。
  3. 能力文档持续补充。每轮迭代暴露的知识缺口当场补进知识库,收益给到之后的所有模块。
  4. 人工审查不省略。AI 的自查能收敛规范问题,逻辑正确性仍然靠人把关。

下一步是把这套流程推到更多依赖干净的纯逻辑组件上,再看「代码分析 → 转写 → 审查 → 合入」还有多少环节可以接起来。