公司的主 App 跑了三年多 Objective-C,今年年初终于下定决心往 Swift 迁。原计划三个月迁完,实际用了五个多月,中间踩的坑值得记一笔。
不要想着一次性迁完。 我们最初的方案是新开一个 Swift 分支,集中人力把旧代码全部翻译一遍。干了两个星期就发现这条路走不通:业务需求不会停,分支落后主干越来越多,合并冲突解到怀疑人生。后来改成混合编译,新的模块用 Swift 写,旧的 OC 代码按模块逐步迁,才把节奏理顺。
bridging header 是个大坑。 项目里如果既有 OC 引用 Swift,又有 Swift 引用 OC,Xcode 的报错信息基本不可读。我们最后的经验是:所有 OC 头文件里用到的第三方类型,尽量在 pch 里收口,别让 Swift 端直接碰到太深的头文件链。
还有一个血泪教训:Swift 4.2 之前 API 变动太剧烈了,我们迁移中途 Swift 4.1 发布,#selector 和 KVO 相关的写法改了不少,又返工了半个月。现在回头看,选对版本窗口期很重要,大版本发布前千万别开迁。
代码示例没什么好贴的,唯一想留的是这条规律:迁移期间新代码的 code review 强度要加倍。Swift 写起来太舒服,新人很容易在 optional 处理上放飞自我,! 满天飞。我们在 CI 里加了 SwiftLint 的 implicitly_unwrapped_optional 规则之后,线上 crash 率才慢慢降下来。
总结:迁移本身不难,难的是在业务不停的情况下迁。如果重来一次,我会在开始前先把模块依赖关系理清楚,从依赖最少的叶子模块开始迁,而不是按页面从上往下迁。