iOS项目最佳做法和工具

带有开源Xcode项目模板

在进行未开发的iOS项目时,我常常不得不从头开始一个新项目。 在这样做的同时,我和我的团队总是在基本项目设置上花费大量时间,例如集成工具,设置项目结构,编写基类,集成外部库等。

我决定可以节省在项目启动上花费的时间,并且该过程基本上可以实现自动化。 我写下了所有常用的最佳实践和工具,并准备了一个项目模板,供我和我的团队在开始新项目时使用。 该模板应节省项目设置时间,并提供每个团队成员都习惯的通用基础,这样您就不必思考和探索项目结构和基础。 他们将永远是相同的。

模板中包含的每一个工具或最佳实践都应该单独发表一篇文章,但我想尝试总结一下每一点,并简要解释为什么要包含它们。

椰子足

我认为不需要对此进行介绍。 这是用于管理iOS项目的外部依赖关系库。 它已经存在了很长时间,并且功能强大,并且已经在成千上万个项目中进行了测试。 还有像Carthage这样的替代依赖管理器,但我决定选择Cocoapods,因为它支持的开源项目范围最广。 使用Cocoapods非常容易,它带有一个搜索索引,可让您轻松发现可能需要的软件包。

模板项目带有一个简单的Podfile,其中包含Swiftlint和R.swift。 该模板还包括一个Gemfile,用于管理用于解析依赖关系的Cocoapods版本。 这是一个经常被忽视的改进,可以防止团队中的开发人员使用不同版本的Cocoapods本身安装依赖项时出现问题。 Gemfile在整个团队中使用相同的Cocoapods版本实施。

斯威夫林特

Swiftlint是一个非常有用的工具,可为团队中的每个程序员强制执行某些规则和编码风格。 您可以将其视为自动化的代码审查系统,该系统会警告程序员有关危险的信息,例如强行拆开,强行强制转换,强行尝试等。但是,通过确保所有程序员都遵循相同的“代码风格”相关规则,可以强制实施通用的编码风格例如缩进或间距规则。 这具有巨大的好处,不仅可以通过进行这些基本检查来节省代码审查的时间,而且还可以使项目中的所有文件看起来都很熟悉,从而提高了文件的可读性,并因此得到了所有开发人员的理解。 您可以在此处找到所有规则的列表。 在模板中,Swiftlint是通过Cocoapods安装的,并包含在“构建阶段”步骤中,因此在每个项目构建时,它都会掉毛并警告开发人员。

斯威夫特

R.swift是一种用于获取强类型,自动完成的资源(如图像,字体集和本地化)的工具。 它通过扫描项目并生成获取资源所需的快速类来完成此操作。 该库的最大卖点是,在使用资源的同时,它使您的代码:

  • 全类型 -更少的转换和猜测方法将返回什么
  • 检查编译时间 -没有更多不正确的字符串使您的应用程序在运行时崩溃
  • 自动完成 无需再猜测图像/笔尖/故事板的名称

考虑使用官方字符串API的以下代码:

  let icon = UIImage(名称:“ custom-icon”) 

如果您拼写错误的图片名称,则会在此处得到零。 如果团队中的任何成员更改了图像资源的名称,则此代码将返回nil或如果您强制展开图像将崩溃。 使用R.swift时,将变为:

 让图标= R.image.customIcon() 

现在,您可以确定图标确实存在(如果不通过编译时间检查,编译器会警告您),并且您不会在图标名称中输入错字,因为您将使用自动完成功能。

R.swift是通过Cocoapods安装的,并作为构建阶段集成在模板中,并将在每次构建时生成Swift包装器类。 这意味着,如果添加文件/图像/本地化/字体/颜色/笔尖等,则在编译项目后即可使用R.swift使用它。

单独的AppDelegate进行测试

一个经常被忽略的良好实践是在运行测试时拥有一个单独的TestAppDelegate类。 为什么是个好主意? 好吧,通常AppDelegate类在应用程序启动时会做很多工作。 它可以设置一个窗口,构建应用程序的基本UI结构,注册通知,设置数据库,甚至有时对某些后端服务进行API调用。 单元测试不应有任何副作用。 您是否真的不想进行随机api调用并设置应用程序的所有UI结构,只是为了运行一些单元测试?

TestAppDelegate还是在测试套件执行期间只希望运行一次的代码的好地方。 它可能包含生成模拟,对网络请求进行存根的代码等。

模板包含main.swift文件,这是应用程序的主要入口点。 该文件包含一些方法,这些方法可以检查应用程序当前在什么环境下运行,如果是测试环境,则调用TestAppDelegate。

编译器性能分析标志

Swift是一种很棒的语言,比Objective-C(IMO)更容易使用和安全得多。 但是,当它首次推出时,它有一个很大的缺点-编译时间。 在Swift的2天中,我正在开发一个包含大约40k行Swift代码的项目(中型项目)。 该代码包含大量泛型和类型推断,并且花费了近5分钟的时间来编译干净的构建。 当您进行了很小的更改时,项目将重新编译,并花了大约2分钟的时间才能看到更改。 那是我有过的最糟糕的开发人员经验之一,因此我几乎停止使用Swift。

当时唯一的解决方案是尝试分析项目的编译时间,并尝试以这种方式更改您的代码,这将使编译器更快。 为了解决这个问题,Apple引入了一些非官方的编译器标志,这些标志会在编译方法主体或解决表达式类型花费太长时间时发出警告。 我将这些标志添加到模板项目中,因此一开始就会警告您应用程序的编译时间较长。

如今,构建时间已大大缩短,您几乎不需要为了提高构建时间而调整代码。 但是,最好还是先了解一下,然后在项目过大时尝试解决问题。

开发/阶段/生产配置

另一个好的做法(或者我可以说是必要的)是为开发,登台和生产环境使用单独的配置和环境变量。 如今,几乎每个应用程序都必须连接到某种后端服务,通常,这些服务部署在多个环境中。 开发环境用于日常部署和开发人员测试其代码。 暂存环境用于稳定版本以供测试人员和客户端进行测试。 我们都知道生产环境是为了什么。

在iOS项目中支持多种环境的一种方法是添加项目级别的配置。

一旦定义了配置,就可以创建一个Configuration.plist文件,其中包含每个环境的变量。

运行项目时,可以指定应使用的配置。 您可以在构建方案中执行此操作。

然后,您需要在项目Info.plist文件中添加一个附加属性。 该属性的值将在运行时动态解析为当前配置的名称。

这些都已在模板中为您预先配置。

剩下的唯一事情就是编写一个可以在运行时根据构建方案中选择的配置检索这些变量的类。 该模板包含一个ConfigurationManager类,该类可以检索当前环境的变量。 您可以在Github上检查该类的实现,以了解其工作原理。

自述文件

每个项目都应该具有基本的自述文件,其中至少包含有关如何安装依赖项和运行项目的说明。 它还应包含对项目体系结构和模块的描述。 不幸的是,开发人员不喜欢编写文档(自述文件是其中的一部分),而且我已经看到开发了数月的项目,他们甚至拥有一个基本的自述文件。 为了减轻编写此基本自述文件的负担,该模板包含一个涵盖安装和项目结构的标准自述文件。 使用模板设置新项目时,将自动包含自述文件。

吉特尼奥雷

如今,大多数项目都使用GIT作为其版本控制系统。 使用GIT时,通常通常不会忽略项目中的某些文件或文件夹,例如build文件夹或派生数据文件夹。 为了避免您搜索适合您的iOS项目的gitignore文件的麻烦,该模板包括Github贡献者提供的标准gitignore。

处理深层链接和通知的基类

如今,几乎每个应用程序都必须处理深层链接和通知。 为此,开发人员必须在AppDelegate类中编写一些样板代码。 该模板涵盖了该内容,还提供了使使用深层链接和通知更容易的基类。

摘要

综上所述,该模板试图包括最佳实践并集成有用的第三方工具。 这可以节省您和我们的团队在新项目设置上的时间,也可以为其余项目提供通用而坚实的基础。 愿它为您服务!

PS:如果您对模板有任何问题或功能要求,请给我一个有关Github的问题。 我会在空闲时间尝试解决该问题。