Apps vs Swift 3

介绍

Swift是一种新的Apple多功能编程语言,于2年前首次亮相。 自从Apple社区不断提供支持以来,自首次发布以来就一直在不断更新。

自Swift首次发布以来,已经有3个主要版本,第三个是今年9月。 那么这是什么意思? 对于使用该语言的开发人员而言,该发行版的改进带有其优缺点的合理份额。

为了获得一个想法,Swift可以与Objective-C系列进行顺畅的交互并使用C标准库提供的某些功能。 随着Swift 3的发布,与这些外部语言的许多用法和连接都得到了迅速重建。 要查看所有官方新功能,请在此处访问Swift网站。

例如,对于那些使用Swift的异步框架在其他线程中执行任务的用户来说,这种处理方式是这样的:

并且由于它具有如此多的全局函数和全局变量,因此Apple对其进行了如下重写:

如您所见,他们正在实施更快速的方法。

同样的变化也适用于其他各种情况。 例如,从旧的Objective-C NS类迁移到新的Swift类。 ( NSTimer->计时器 )。

注意:最后一个示例不是名称的重构,而是类解决方案的整个重构。

Swift 3的许多改进还带来了不便(或我们可能不习惯的过程)。 现在,必须迁移正在使用的应用程序,以支持新版本的OS和IDE XCode。 此外,与以前的版本相比,此新版本的Swift具有不可计数的重大更改。 因此,必须移植可用代码的各个部分,并找到一些解决方法,以解决不再存在的部分。 这也意味着您正在使用的库也必须建立端口,因此不再维护的库可能会被弃用。

听起来可能有些不知所措,但是,Swift添加了一个内置插件来自动移植代码。 是的,它有缺点,因此请记住,对于那些使用许多框架和复杂代码的应用程序,插件可能还不够。

这使我想到了这篇文章的想法…

要了解如何移植具有许多框架和复杂结构的应用程序,您将获得移植自己的应用程序所需的工具和资源!

应用程序

我们正在迁移的应用程序以iOS 10或更高版本为目标,并使用迦太基来管理项目的依赖项。 当前,我们正在使用Fastlane处理部署,测试,证书和供应配置文件,使用Parse存储数据,使用AWS包含具有Lambda功能的Parse服务器。 这样,某些应用程序后端逻辑就处于无服务器架构中。

该应用程序还使用由Objective-C制成的具有较低层的桥接器,以通过蓝牙与基于外部硬件的模块进行连接。 以及使用S3存储各种文件。

有用的资源:https://martinfowler.com/articles/serverless.html

准备

估算工作量

为了估算工作量,我们建议使用功能点技术。 此技术可用于根据任务的历史工作量,大小和不确定性来客观地衡量任务。

不幸的是,使用这种方法,我们发现无法拆分迁移以更好地衡量所涉及的任务。 这是由于以下事实:一旦您开始迁移代码,该应用将无法编译或正常运行,直到完成为止。 相信我,这个过程可能需要几个小时甚至几周的时间。

依存关系

移植之前,必须检查依赖项的发布。 在最好的情况下,所有依赖项都将完成移植,但是现实是,许多依赖项可能尚未移植其项目。 因此,在这种情况下,您有两种选择:估算删除依赖项的成本,并针对迁移依赖项的成本实施临时解决方案。

不可避免地,您必须在这两个选项之间做出决定。 可能发生的最糟糕的情况是,不维护依赖项,并且无法从维护者那里接收任何端口。 在这种情况下,您可以从库中进行预搜索,也可以建立端口并向项目提交“拉取请求”。 在开始迁移之前,必须先检查依赖项的状态。

IDE和设备

如果您要定位新版本的OS,则必须至少有一个在iOS 10或更高版本上针对移动设备运行的设备,在其他平台上等效。 此外,您必须下载Xcode 8或更高版本才能创建端口。

迁移过程

由于规模,我建议将项目分为5个部分:

  1. 依赖性 :从Cartfile或CocoaPods配置更新依赖性,以移植它们。
  2. 项目编译:使用嵌入式插件移植代码,然后对其进行重构,以便项目可以编译
  3. 测试编译:移植测试以编译整个应用程序。
  4. 业务逻辑:根据Swift 3标准,重构应用程序的业务逻辑以使其正常运行。
  5. 测试逻辑:与业务逻辑一起重构测试,以消除应用程序中的所有不一致之处
  6. 质量检查:对所有功能进行全面的质量检查,以避免任何退步。

保持井井有条非常重要,以便正确完成迁移。

现在,让我们将此过程发挥作用。

依存关系

在我的情况下,我们删除了2个未移植的依赖项,并分别移植了1个,从而对最终合并到master的项目进行了PR。 注意:如果您在应用程序中使用ReactiveCocoa,建议您访问Github页面以查看已更改的内容。

使用新版本的依赖关系更新Cartfile后,必须对其进行更新。 请在此处密切注意,因为您可能会遇到迦太基无法完成更新的情况。 如果是这种情况,请注意以下几点:

  • 确保所有依赖项都已移植到Swift 3。
  • 对于您必须移植的任何内容,请记住在Cartfile中更新依赖项的入口。 它看起来应该像这样: Github“ ReactiveCocoa / ReactiveObjCBridge”“ master”
  • 您可以运行此更新,在Carthage的update命令中添加— no-use-binaries标志。 这样,您就可以在本地构建依赖项,而不是使用可能仍在使用较旧版本的编译器的预构建框架。

项目编译

项目编译绝对是迁移过程中最繁琐的任务。 这就是为什么。

正如我在上面简要提到的那样,Swift Migrator工具是嵌入式插件,可帮助您进行初始代码重构。

迁移器工具的问题在于,处理所有源文件以进行更改需要很长时间。 我的建议是多次运行该工具,因为它很可能会继续寻找要在代码中进行替换的工具。 使用此工具找到所有更改后,即可开始进行自己的更改。

于是战斗就开始了:众所周知,编译器有时无法生成SIL,因此在您工作时崩溃。 好消息是,这很容易检测! 最好的指示是文件中的文本不再突出显示并且没有有关拼写错误的信息(有关编译器体系结构的更多信息,请单击此处)。

通常,当您使用嵌套块或使用FlatMaps时使用Reactivecocoa的块时,会发生这种情况。 现在您的大多数代码很可能处于编译器无法正常运行的状态,因此崩溃了,仅显示了一些要修复的错误。 尽管一次攻击一个文件夹(或逻辑)迁移可能很诱人,但这最终只会向您显示编译器想要的错误,而不是您正在寻找的错误。 如果是这种情况,请参考以下提示,在没有编译器帮助的情况下修复错误:

  • 有了新的Enum指南,您现在可以搜索实现以对其进行重构。 (它们不再是大写)
  • 许多类的Objective-C SDK不再扩展NSObject。 这意味着存在具有相同名称但没有前缀NS(NSURL-> URL)的新结构。
  • NSDate已重新实现为Date,但某些功能已拆分为Calendar和DateComponents。 要查看用法并重构逻辑,请查看这篇文章。
  • 现在,大多数返回AnyObject / NSError的SDK新实现都将返回Any / Error来变得更通用。

请注意:对于使用ReactiveCocoa和Rex的用户:

Rex在Swift 3中不再存在,因为ReactiveCocoa已将所有扩展和UI绑定添加到主项目中。 该项目已分为更多包含的项目。 这意味着所有使用该库中大多数核心反应性原语的文件现在都必须导入ReactiveSwift库而不是ReactiveCocoa。 您可以在没有编译器帮助的情况下使用XCode的搜索功能进行此更改。 您可以在此处访问ReactiveCocoa主页。

这是否意味着ReactiveCocoa不再存在?

正确的答案是“否”,ReactiveCocoa仍然存在,但是现在它具有一些有限的功能,例如上面提到的UI绑定。 这是什么意思? 现在,您在任何地方导入Rex都将导入ReactiveCocoa。 不幸的是,由于绑定更改了其体系结构,因此更改并不是那么简单。 最初,绑定看起来像这样:

现在它们处于代理模式下,看起来像这样:

ReactiveCoca删除了许多绑定,因为它们导致了反模式。 如果您的情况也是这样(您的情况也是如此),那么您必须在视图中的其他位置(例如在ViewModel中)移动逻辑。

要更精确地修复错误,您可以做的另一件事是一次输入一个文件。 这样,编译器仅在您输入的文件中检查错误。 这个过程通常需要几秒钟,但是当它正常工作时,您将最终在编译器的有限帮助下修复错误。

我的建议:使用XCode的搜索文本功能进行所有替换。 这样,您就可以消除错误,而不会抱怨编译器。

有关更多信息,请查看“快速迁移”页面。

测试编译

在修复应用程序中的错误时,您会注意到编译器能够构建指向项目中所有剩余错误的所有文件。 解决了项目中的所有错误后,即可对测试应用相同的过程。 这一步比整个项目要简单得多。

商业逻辑

一旦项目和测试正确编译,就可以开始修复运行时错误。 对于此过程,您可以使用XCode随附的Swift错误和异常断点。 尽管它不能解决所有问题,但绝对有帮助。

测试逻辑

希望测试将在第3阶段进行更新,但是,有时逻辑会发生巨大变化,从而导致与测试不一致。 另一种可能是重构器插件更改了代码,导致测试无法正常工作。

好消息是,检查您的测试以及应用程序的逻辑正常运行不会花费太多时间。

质量检查

这一步的解释很简单,但是每个项目的复杂性会有所不同。 迁移应用程序后,您必须进行全面的质量检查测试,以搜索应用程序中的错误。 这可能需要一段时间,所以要耐心,因为即使您在这里花费了一半的时间,但如果您在此处结束应用程序的运行方式与以前完全一样,但使用了新的语言标准,这将是一笔不错的投资。

完成此操作后,您的应用就可以使用了!