目前,绝大多数关于 SwiftUI 的教学内容都聚焦于小项目和示例应用,却从未解释在一个由 20 多名 iOS 工程师开发、拥有 5 亿用户的应用里,落地 SwiftUI 究竟意味着什么。本文试图填补这一空白,并展示如何在不拖垮团队、不搞崩应用、不辜负用户信任的前提下顺利落地。
在 5 亿用户级的应用中落地 SwiftUI 的经验教训
目前,绝大多数关于 SwiftUI 的教学内容都聚焦于小项目和示例应用,却从未解释在一个由 20 多名 iOS 工程师开发、拥有 5 亿用户的应用里,落地 SwiftUI 究竟意味着什么,本文试图填补这一空白。
我至今清晰记得当我意识到 SwiftUI 落地会比预想难得多的那个瞬间:我们当时正在开规划会,有一位经验最丰富的 iOS 工程师,他是一位已经使用 UIKit 开发功能近十年的人,看着我说:“我明白 SwiftUI 是未来的趋势。但我现有的页面运行正常、速度快、不崩溃。我为什么要重写它们?”
他不是在故意刁难我们,而是在说实话。而这份坦诚,暴露了任何教程或 WWDC 专题都没让我准备好的问题。
大规模落地 SwiftUI 的挑战并不在于框架本身,框架本身没问题。挑战在于技术与必须使用它的工程师之间;在于说服资深工程师放弃一套运行良好的方案时涉及的团队博弈;在于那些没人提前提醒过的权衡取舍;在于和产品经理沟通,他们无法理解,为什么一个功能突然要求 iOS 17,而你一半的用户还在用 iOS 15。
过去三年,我在一款月活 5 亿用户、覆盖 190 个国家的消费级应用里全程处理了这一切。下面是我的经验和教训。
资深工程师的问题
你最优秀的 iOS 工程师大概率并不想要 SwiftUI,这与害怕改变无关。这些人花了数年的时间,用 UIKit 筑起了一座“堡垒”。他们熟悉每一面墙、每一条通道、每一间暗室。UIKit 从 2008 年诞生至今,所有边缘场景都已有完善的文档,每一个布局怪癖都有 Stack Overflow 上超过 400 个赞的答案,每一段动画时间曲线都已有前人踩坑和优化。资深工程师已经建立了围绕 UIKit 的心智模型,在睡眼朦胧时他们都能调试问题。看一眼视图控制器,他们就能逐行、逐像素地知道会发生什么。
2022 年发布的 SwiftUI 完全做不到这些。预览随时会无故失效;导航栏往好了说也只是“半成品”;真实负载下的性能难以预测且令人沮丧。对 SwiftUI 最兴奋的反而是从业不足四年的工程师,他们从未形成对 UIKit 的肌肉记忆,因此没有旧习惯需要抛弃。对他们而言,UIKit 就像戴着烤箱手套写代码。

UIKit 老手与 SwiftUI 拥护者之间的差异:这是文化问题,而非技术问题
这在团队内部形成了一种无声的分裂。虽然没有敌意,但可以真实感觉到。资深工程师觉得新人在追逐花哨的新玩具;新人觉得老手在用十年前的模式“挟持”代码库。双方都有合理的理由,也都不愿意完全让步。
解决方案并不在于技术层面,而是文化层面。我们制定了一条简单的规则:只有新功能允许用 SwiftUI 实现。不重写现有的 UIKit 页面,不为了迁移而迁移。如果你在开发新功能,并且目标系统是 iOS 17 及以上,那么就要用 SwiftUI。其他一切继续保留 UIKit 方案,直到有产品层面的理由需要改动。
这让资深工程师能在核心链路保持高效交付,同时通过低风险任务逐步建立对 SwiftUI 的熟悉度。也让新工程师获得了他们一直想要的、以 SwiftUI 为先的工作流。没人感到被胁迫,也没人觉得被抛弃。紧张氛围没有一夜之间消失,但逐渐缓和为富有成效的状态。
iOS 的版本陷阱
这也是苹果在 WWDC 上不会告诉你的事情。
用户更新手机的速度,远不如 Craig Federighi 假设的那么快。一款数亿用户的消费级应用不可能一夜之间放弃对 iOS 14 和 15 的支持。使用这些系统版本的是真实的用户,关联着真实的收入,在做出任何决定前,都必须与业务方进行务实的沟通。这些沟通由数据分析和用户数据驱动,而非开发者的热情。
问题在于,SwiftUI 最好的特性只在最新的 iOS 版本上开放。就像一家餐厅不断推出惊艳菜品,却只允许开当年新款汽车的人点单。

SwiftUI 最佳功能被锁在最新 iOS 版本上:对用户基数庞大的应用是硬性约束
在 iOS 17 之前,SwiftUI 状态管理依赖 Combine 与ObservableObject,它们极易触发整个视图树不必要的重绘。iOS 17 中的Observation框架修复了这一问题,让更新更精准,也就是只有读取特定属性的视图才会重绘。这是 SwiftUI 在真实负载下性能表现的根本性转变。但是,如果你的应用仍需支持 iOS 15,那么就完全无法使用它。
我们通过特性标记和按功能设置最低版本来处理这一问题。面向 iOS 17+的 SwiftUI 页面会对旧版本用户屏蔽,这些用户要么看到基于 UIKit 的兜底页面,要么直接跳过该功能。产品团队必须理解并接受这一权衡。这让功能规划更复杂,但却是唯一务实的做法。当底层技术只对部分用户友好时,你无法向所有用户承诺相同的功能。
设计系统的难题
在这方面,依然没人提醒你,但是它会让所有团队措手不及。
如果你的应用已经有成熟的设计系统(任何大规模正规应用都会有),落地 SwiftUI 实际上意味着要从头重建一套。团队日常依赖的 UIKit 组件,比如按钮、卡片、输入框、字体、主题,它们都不会自动变成 SwiftUI 视图。你必须从零重构,保持两套视觉完全一致,并在设计迭代时始终做到完美同步。

混合落地意味着:在完全迁移前,必须并行维护两套设计系统
这在实践中意味着,你现在需要维护两套看起来必须完全一样的设计系统。设计团队更新按钮样式时,需要有人在两处同时修改;推出新组件时,需要构建两遍。这种“维护成本”会一直持续到迁移全部完成,对大型应用来说,这可能需要数年的时间。
我们当年在 UIKit 上遇到过这种困境,因此在 SwiftUI 上没有重蹈覆辙。我们从第一天起就让设计系统支持主题感知,每个组件都应接收主题上下文,让暗黑模式、A/B 测试变体、地区定制化全部自动生效。如果一开始就把基础打好,后续就能避免痛苦的改造。
2026 年,SwiftUI 真正做得好的地方
经过观察苹果在每届 WWDC 上对框架的迭代,SwiftUI 已经成熟为一款真正优秀的框架。以下是它在生产环境中真正体现价值的地方。
开发原型的速度:用 SwiftUI 开发新功能页面比等效的 UIKit 快约 40%,尤其是 Xcode 17+预览几乎瞬时加载。对希望快速验证想法的产品团队而言,这就像从自行车换成摩托车。路还是那条路,但速度天差地别。
状态驱动 UI:不再需要手动调用 reloadData()。也不再需要让数据模型与视图维持脆弱的同步,这导致我们每三个冲刺周期就会出问题。iOS 17+的 Observation 框架让状态管理可预测、高性能。你设置状态,UI 就会自动反映。在手动管理状态多年之后,仅此一点,就像让我们卸下了千斤重担。
跨平台覆盖:一套 SwiftUI 功能可同时支持 iOS、macOS、watchOS,代码复用率约 90%。如果你的公司在多个苹果平台发布产品,这能消除过去需要独立团队承担的大量重复工作。
动画:PhaseAnimator和KeyframeAnimator能够让你用几行声明式代码实现复杂、多阶段的动画。同样效果在 UIKit 中可能需要数百行代码、嵌套的完成回调,以及耗费一整个下午调试的时间曲线。对需要靠视觉精致度拉开差距的消费级应用而言,这是真正的竞争优势。
Liquid Glass 时代:苹果 2026 设计语言以 SwiftUI 为优先。自适应材质、流畅反光、同心形状等效果,使用标准 SwiftUI 容器即可免费获得。在 UIKit 中实现这些效果本身就是一项重大的工程。苹果已经非常明确地指明了开发者未来的方向。
SwiftUI 仍然不足的地方
坦诚面对短板,比盲目鼓吹更重要。如果你要大规模落地这个框架,你有权知道它有哪些缺陷。
超大数据列表:当列表超过 10,000 条、使用复杂单元格时,UIKit 的 UICollectionView 在帧率上仍然略有优势。它们的差距不大(60 FPS vs 大约 58 FPS),但在严重依赖滚动的消费级应用中,用户指尖能感受到细微的卡顿,不过,他们可能说不清问题出在什么地方。
自定义集合布局:如果你需要 Pinterest 风格的交错网格、复杂的插入动画,LazyVGrid 过于僵硬,无法实现。超出基础网格的复杂布局,你仍然需要使用带组合布局的 UICollectionView,而且这一点短期内不会改变。
精细化滚动控制:如果要编程获取精确滚动速度或像素级偏移,在 UIKit 中依然会更直观。SwiftUI 的ScrollView虽然在 iOS 17 加入了滚动过渡、iOS 18 加入目标行为后大幅改进,但控制能力仍不如 UIKit 完整。
旧系统支持:iOS 16 以下没有 NavigationStack;iOS 17 以下没有 Observation 框架和 SwiftData。最好用的 SwiftUI 必须搭配最新的 iOS,这是一个你必须规划适应的约束,并不是靠一厢情愿就能消除的。
关于测试的简要说明
我不会在此深入介绍测试相关的话题,因为它值得单独写一篇文章,但我只想说,测试体系是我们团队支持采用 SwiftUI 的最强理由之一,而且完全出乎我们的意料。
SwiftUI 声明式、状态驱动的特性,让测试与 UIKit 截然不同。你可以用 ViewInspector 等工具直接对视图进行单元测试,而不必依赖缓慢、不稳定的XCUITest。你只需测试 ViewModel 状态即可验证 UI,因为只要状态正确,UI 就必定会正确反映它。通过预览实现快照测试变得极为简单,依赖注入则通过@Environment得到了天然的支持。当我们把这一切与基于协议的模块化架构结合后,代码覆盖率从 20%左右提升到 70%以上,甚至从未写过测试的工程师也开始主动编写测试了。
话虽如此,SwiftUI 也有自身的测试挑战,尤其是视图层级不透明、需要规范使用.accessibilityIdentifier()等。更多内容将在后续文章中展开阐述。
结论
在消费级大规模应用中落地 SwiftUI,不是一个技术决策,而是一个组织决策。
过去几年,框架本身已经相当成熟。Observation框架修复了状态管理,NavigationStack让路由变得更可靠,Liquid Glass 设计让 SwiftUI 成为苹果设计方向上唯一合理的选择。技术地基稳固,且每届 WWDC 都在使其变得更好。
但是,如果资深工程师感到被排斥、产品团队不理解为何功能突然要求 iOS 17、设计系统跟不上双框架并行,那么一切技术优势都将毫无意义。真正阻碍落地的是这些问题,而它们没有技术方案。它们需要耐心、清晰沟通,并愿意让组织的不同部分以不同速度推进的包容度。
对我们来说,有效的方案原则非常简单,但是实现起来并非坦途:新功能用 SwiftUI,现有代码保留 UIKit,所有功能加开关,绝不强制进行无用户价值的重写。这听上去不够高端,也无法在大会上做出漂亮的前后对比幻灯片,但它行之有效。三年过去,代码库的状态远好于我们当初试图一次性全面迁移的结果。
SwiftUI 是 iOS 开发的未来,这一点毋庸置疑。真正值得探讨的,是如何在抵达未来的路上,不拖垮团队、不搞崩应用、不辜负用户的信任。
查看英文原文:Lessons from Adopting SwiftUI in an App with 50 Million Users





