iOS应用程序持续交付的力量

可以说,要使团队超越一个人,最具挑战性的方面之一就是确保每个人都拥有相同的环境 。 不仅所有团队成员都需要了解项目的高层计划和目标-有效共享正在进行的功能和里程碑的确切状态对于团队协作至关重要,这确实至关重要。

从设计到实施

举例来说,假设设计师一直在为应用程序开发新屏幕,并且团队已决定是时候开始在代码中实现该新屏幕了。 设计师将他们的设计及其所有资产交给开发人员,然后他们开始在Xcode中构建新屏幕。 由于估计需要一到两周的时间,因此设计师将继续执行下一个任务,具体取决于公司的规模,这可能需要与全新的开发人员,产品经理,测试人员和其他设计师合作。

但是,这种交接几乎从来不是一个干净的中断 。 交付给开发人员的设计很可能无法回答他们所有的问题,而且某些细节常常会在翻译过程中“丢失” -不是由于能力不足,而是因为我们尚未建立共享关系上下文。 我们理想的情况是,设计师/开发人员的交接实际上根本不是交接,而只是连续反馈循环中的又一步。

如果我们能够在完成设计工作之前获得设计人员对设计实现的反馈,那么我们更有可能对这些反馈采取行动,并且在我们解决问题之前要正确无误。无论如何都要运送我们已经建造的东西。 一遍又一遍地讲, “我们将在下一版本中对其进行修复”可能是一件令人沮丧的事情。

持续集成

在iOS开发者社区中,我们早已意识到持续反馈的价值-通过持续集成的日益普及。 使用像Bitrise这样的服务,我们可以通过为所有受支持的设备构建应用程序并在结果上运行我们的自动化测试套件,lint和其他工具,来快速获取有关推送到远程存储库的任何代码更改的反馈。

最重要的是,使用诸如GitHub Pull Requests之类的方法添加同行评审,我们已经建立了持续的反馈循环-在其中,作为一个持续的过程,代码被编写,审查,测试并集成到主要代码库中。 这不仅使我们的工作流程更流畅,而且还为错误提供了安全网。 错误甚至可以在合并之前就被捕获,可以解决和重新测试版本控制冲突,并且可以调整体系结构不一致之处。

可以说,一旦您完成了使用持续集成的项目,就很难在没有项目的情况下恢复工作。 那么,我们如何才能扩展持续集成模型,使其不仅成为开发人员的工作流,而且使我们团队的其他成员(例如设计师,产品经理或外部利益相关者)参与其中? 输入连续交付

持续交付

如果绿色的构建和通过测试的套件不是我们持续集成过程的终点,又该如何每个构建实际交付给我们的团队怎么办? 这样,我们不仅可以使开发人员,而且可以使我们团队中的每个人都进入我们的反馈循环。 设计师可以看到其实施设计的确切状态,产品经理可以制定更准确的计划,而外部利益相关者(例如代理商或自由职业者的客户)可以随时透明地看到其项目的确切状态。

虽然连续交付已成为Web和后端开发之类的越来越普遍的做法,但在iOS上却有些棘手-因为我们无法真正将所做的每项更改都部署到App Store或什至实际上是TestFlight (取决于更改的数量)。 值得庆幸的是,Bitrise可以解决此问题。

通过将Xcode Archive & Export for iOSXcode Archive & Export for iOS步骤添加到Bitrise工作流程,新的IPA(app)工件将被存档并保存到每个版本中。 将该步骤链接到Deploy to Bitrise.io步骤将依次获取该IPA文件并将其部署到Bitrise的内部测试服务。 完成后,您在Bitrise上邀请加入该应用程序的每个人都可以访问这些版本。

代码签名

难题的最后一步是确保已部署的应用程序以能够在所有团队成员的设备上运行的方式进行代码签名。 为此,有四个主要选项:

  1. 如果您的公司拥有Apple 颁发企业证书 ,则可用于在团队内部内部部署应用程序。 确保已将应用程序设置为使用Bitrise Workflow编辑器中“ Code Signing选项卡中的企业证书进行Code Signing
  2. 在您的Bitrise工作流程中使用iOS Auto Provision步骤。 这将自动在Apple Developer Portal中注册任何新设备,并在部署应用程序之前确保该应用程序的配置文件是最新的。
  3. 在工作流程中使用Fastlane Match步骤,以通过fastlane match下载和安装证书和配置文件。
  4. 手动管理应用程序的代码签名。

一旦上述内容就位,Bitrise将自动管理未来的持续交付过程。 当有新版本可用时,将通知团队成员,并且可以轻松地将这些版本添加到他们的设备上。

超越Beta

虽然我们现在已经建立了一个平稳的过程来确保团队中的每个人都知道我们正在构建的应用程序的当前状态,但是持续交付的真正力量实际上来自使我们开始形成的例程。 由于我们现在实际上是在交付我们所做的每个变更,即使它只是目前在我们团队内部,所以它提高了每个变更需要达到的质量水平的标准。

就像持续集成最常导致更少的master分支中断以及通过自动测试,整理和同行评审之类的方法来提高代码质量一样,当我们开始习惯于持续交付应用程序时,我们可以获得相同的效果,但是在应用的整体用户体验。 一旦我们稳定了用户体验的质量,使其在开发过程中不会降低,然后在发布之前就进行了修复,那么某些真正有趣的事情就变得可能了。

想象一下能够随时发布我们的应用程序。 没有漫长的发布过程,没有在数周内停止开发功能来修复大量错误,也没有长时间的加班工作来满足特定的发布窗口。 相反,持续交付的最终目标是习惯于交付应用程序,使其可以基于master分支中当前的任何提交来完成。

功能标记

为了能够随时发布应用,我们不仅需要更改流程以及集成和交付代码的方式,还可能需要进行一些实际的代码更改 。 特别是,对于每个发行版,我们很有可能在我们的存储库中包含尚未准备就绪的代码。 它可能是尚未完全实现的功能,需要在整个应用程序中传播的UI更改,或者需要与某种形式的营销工作协调的功能。

无需在发布之前手动取出此类正在进行的代码(扩展性就不会很好,因为我们可能会加大连续交付的工作量),我们可以利用功能标志来动态启用或禁用给定我们应用内的代码路径。

尽管可以通过多种方法在iOS上实现功能标记,但快速而轻松的入门方法可以是简单地创建一组附加到某些FeatureFlags类型的静态Bool常量。 这些常量的值可以是硬编码的,也可以基于其他一些值,例如,构建应用程序所用的配置,例如以下Swift结构:

 struct FeatureFlags { 
static let allowLandscapeMode = true
static let enableSocialFeature = false
static let useRoundImageStyle = AppConfig.isForInternalUse
}

完成上述操作后,我们现在可以轻松地检查是否应启用给定功能,如果不启用,我们将退出任何激活该功能的代码路径-例如,在此处我们在添加功能之前验证FeatureFlags.enableSocialFeature是否为true我们正在构建的视图控制器的社交视图:

 extension ArticleViewController { 
func addSocialViewIfNeeded() {
guard FeatureFlags.enableSocialFeature else {
return
}
  let socialView = SocialView() 
socialView.delegate = self
view.addSubview(socialView)

...
}
}

尽管以上内容是功能标记系统的非常简单的版本,但它可能包含更多高级功能-例如从远程服务器动态下载每个标记的值,或使团队成员调整其值-从简单开始是关键,并且即使是第一次迭代(如上述迭代)也可以使我们走得很远。

一旦我们能够打开或关闭特定的代码路径,我们就可以轻松隐藏不应向最终用户公开的任何功能,同时仍保持其对开发活动的积极性,甚至可能对内部测试也是如此。 当我们能够随时将应用程序交付生产时,这不仅对开发人员非常方便,而且使我们进一步朝着真正的连续交付方向发展。

结论

持续交付可以为应用程序开发团队的工作流程增添无比强大的功能。 通过让所有人(不仅是开发人员)参与到应用程序中新功能的实现过程中,我们可以更轻松地在团队之间建立共享环境,减少额外的会议和同步需求,并避免误解。

然后,一旦我们习惯了不断在团队内部内部交付代码,那么我们很有可能能够在该过程中不断迭代直到有一天能够将新版本的应用程序发布到应用程序中随时存储-基于存储库的master分支中的任何提交。 这不仅会鼓励我们始终将应用程序保持在高质量状态,而且还可以大大减少将代码交付给最终用户所需的开销。

你怎么看? 您的团队目前是否使用某种形式的持续交付,还是您会尝试使用? 让我在Twitter @johnsundell上知道。 而且,如果您正在寻找可用于持续集成/交付需求的服务,那么Bitrise就是最好的选择-这是我个人的最爱。

谢谢阅读! 🚀