cover of episode 246: Hard Forks

246: Hard Forks

2022/7/6
logo of podcast Under the Radar

Under the Radar

AI Deep Dive AI Chapters Transcript
People
D
David Smith
独立的 iOS 开发者,著名应用 Pedometer++ 的创作者。
M
Marco Arment
Topics
Marco Arment: 我在应用开发中面临着巨大的挑战,那就是应用中存在大量的遗留UI代码。我的应用已经使用了八年,期间经历了Swift和SwiftUI的更新,以及UIKit底层的大量改进。这些遗留代码给我带来了巨大的压力,使得我难以进行更改、更新设计和向前发展。我曾经考虑过重写整个UI,但这通常是一个糟糕的主意,因为这相当于对应用进行大规模重写。 几周前,David提到了一个有趣的替代方案:创建一个应用代码的分支,在满足特定条件(例如最新的iOS版本或测试模式)下切换到新的UI,同时保留旧的代码。起初我以为这是一个糟糕的主意,但经过思考,我发现这可能是一个可行的方案。 我之前在watchOS上进行过类似的迁移,当时SwiftUI取代了糟糕的WatchKit。我犹豫过,但最终还是从头开始编写了新的SwiftUI版本,结果非常好,这让我开始考虑在iOS应用上尝试这种方法。虽然SwiftUI仍然感觉像是在使用beta版本,并且在iOS上存在一些挑战,但我仍然认为应该尝试这种方法。 我的应用存在三个问题:使用旧版本的UIKit、主要使用Objective-C以及没有使用SwiftUI。如果要进行大规模重写,我希望一次性解决这些问题,而不是逐步迁移。我被旧代码拖累,难以进行开发,需要一个大型的现代化项目来解决这个问题。 我之前在重构过程中,对于已经用Objective-C编写的代码,选择保留而不是重写,这最终导致了技术债务的增加。我之前保留Objective-C代码的决定是错误的,这增加了技术债务,并阻碍了迭代过程。现在我后悔了,未来将采用干净的重写方式来偿还技术债务。我需要使用新的Swift异步特性,这需要对现有的CloudKit代码进行迁移。 我尝试重写“正在播放”屏幕时遇到了困难,因为同一个视图控制器同时处理最小化和展开状态。我尝试使用SwiftUI的导航功能,但遇到了很多问题,最终放弃了。 David Smith: 我之前也采取过这种“硬分叉”的方法。应用的演进通常是增量的,但这种方式会让我们始终受限于过去的方式。从零开始重写,可以摆脱增量更新的束缚,并利用已有的经验和预期来构建新的UI。 在watchOS引入SwiftUI之前,WatchKit非常糟糕,而SwiftUI需要watchOS 6.0。我保留了旧的WatchKit版本,并使用SwiftUI构建了新的版本,根据watchOS版本条件性地加载不同的UI。大多数用户更倾向于保持应用不变,而不是接受任何更改,因此这种方法带来的用户困扰较少。 针对Pedometer++ watchOS应用的重写,最终结果比之前的版本更好,性能更高。处理iOS版本兼容性问题,一个好的方法是针对最新的iOS版本进行重写。这种“硬分叉”的方法最终会让旧版本逐渐消失,只留下新的、现代化的代码。 虽然这种方法看起来很疯狂,但我过去用它取得了很好的效果,并且会继续使用这种模式。如果我们从未更改过应用,那么旧版本代码可以正常工作很长时间。接受旧代码可以正常工作的事实,可以让我们更自由地构建新功能。 实际上,旧代码通常不会造成问题,维护两个版本的工作量可能比想象的要小。一个稳定且没有bug的应用可以长时间保持稳定运行。重写也是一个机会,可以改变我们构建应用的方式,不仅仅是代码的现代化,更是思维和结构的现代化。 使用SwiftUI开发就像水流下山一样,遇到阻力时,应该考虑是否使用了正确的方式,而不是抱怨框架的限制。我非常喜欢SwiftUI,而使用UIKit则感觉很困难。如果不追求速度,那么坚持使用旧技术也没问题;但要实现现代化,就必须拥抱未来。 成为Swift和SwiftUI专家对iOS开发者来说非常重要,这将决定未来的机遇和成功。逐步迁移的方式会让我们始终无法摆脱过去的束缚,而全面的重写则可以让我们拥抱未来。如果专注于重写,那么在几周内就能构建出一个基本可用的Overcast版本。即使最终决定放弃这种方法,也能获得SwiftUI开发经验,并且不会破坏旧版本。

Deep Dive

Chapters
Marco is stressed by the legacy UI code in his eight-year-old app. David suggests a "hard fork" approach: creating a separate UI branch, which can be conditionally switched to. This approach is compared to incrementally updating the app, like Gromit building train tracks in front of his train.
  • Legacy UI code causes stress and hinders updates.
  • Hard fork approach: creating a separate UI branch.
  • Comparison to incremental updates (Ship of Theseus).

Shownotes Transcript

Rewriting major parts of your app with aggressive new targets while keeping the old code around for compatibility.

This episode of Under the Radar is sponsored by:

  • Sourcegraph): Universal Code Search. Move fast, even in big codebases. Try it now.

Links and Show Notes:

Support Under the Radar with a Relay FM Membership)