iOS 最佳实践[译](一)起步

iOS 最佳实践(一)起步

为什么整理这篇文档?

刚开始从事iOS开发会有一点让人心生畏惧。SwiftObjective-C并不是被广泛使用的语言,这个平台几乎所有内容都有自己特有的名称,将你所编写的代码运行到一台设备上的过程可能是很坎坷的。这份文档就是来帮助你的,不论你是开始迈出你在Cocoa王国中的第一步还是对于以正确的方式编程。下面所有的内容都仅仅是建议,所以如果你有一个很好地理由用不同的方式来实现,那就去做吧!

目录

如果您正在寻找特定的内容,您可以从这里直接跳到相关部分。

  1. 起步
  2. 常用库
  3. 架构
  4. 存储
  5. 资源
  6. 编码风格
  7. 安全
  8. 诊断
  9. 分析
  10. 编译
  11. 分发
  12. 内购(IAP)
  13. 证书

起步

人机交互指南

如果你来自其它平台,请花一些时间来熟悉苹果的人机交互指南。iOS的世界非常强调要有一个良好的设计,你的app也不应例外。该指南还为设计人员提供了一个关于原生UI元素、以及如3D Touch或Wallet等app以及图标大小的实用概述。

Xcode

Xcode是大多数iOS开发者所选择的IDE,同时也是苹果官方指定的唯一平台。除了Xcode外,还有一些替换方案,其中AppCode可以说是最出名的了,但除非你是经验丰富的iOS开发者,否则还是请使用Xcode吧。虽然它有一些缺点,但它现在确实很实用!

如需安装Xcode,直接在Mac的App Store上下载即可。它提供了最新的SDK和模拟器,您可以在首选项>下载中安装更多的东西。

项目设置

当开始开发一个iOS项目的时候,一个常见的问题就是纯代码还是通过StoryboardsXIB文件来使用Interface Builder。众所周知两种方法都能完成工作。然而,这里有几点需要考虑的:

为什么使用纯代码?

  • Storyboards由于其复杂的XML结构,更容易发生版本冲突。这使得比纯代码更难完成合并。
  • 纯代码更容易构造和重用视图,从而保持代码库的DRY
  • 所有的信息都在一个地方。在Interface Builder中,你必须单击所有检查器才能找到您要查找的内容。
  • Storyboards引入了代码和UI之间的耦合,这可能导致崩溃,例如当outletAction没有正确被设置时。编译器不会检测到这些问题。

为什么使用Storyboards?

  • 对于不太倾向于技术的人来说,Storyboards是直接为项目做出贡献的好方法。例如,调整颜色和布局约束。然而,这是需要一个可行的项目设置并且花时间学习基础知识的过程。
  • 由于可以在不构建项目的情况下预览更改,对于迭代开发来说更有优势。
  • 自定义字体和UI元素都是以图形化的方式展现在Storyboards中,当在设计时对最终的外观有一个更好的了解。
  • 对于size classes, Interface Builder 能将你所选择的设备提供实时布局预览,包括iPad分屏多任务处理。

为什么不两者兼用呢?

为了两全其美,你可以采取混用的方案:首先用Storyboards勾勒出最初的设计,对修补和快速更改非常有用。你甚至可以邀请设计师加入到这个流程中。随着UI的成熟和可靠性变得更加重要,你将过渡到更容易维护和协作的基于代码的方式开发。

忽略文件

将版本控制引入项目的第一步就是要有一个正确的.gitignore文件。这样,不需要的文件(用户设置文件,临时文件等)将永远不会被纳入版本库。幸运的是,GitHub 已经提供了 OCSwift.gitignore文件。

依赖管理

CocoaPods

如果你打算在项目中引入第三方库的话,CocoaPods 提供了简单快速的集成。安装它很简单,如下:

1
sudo gem install cocoapods

初始化时,跳转到项目路径下,执行如下代码:

1
pod init

这会自动生成一个Podfile文件,这个文件用来管理项目的所有依赖。在Podfile中添加好依赖后,执行如下代码:

1
pod install

执行后会安装所依赖的第三方库,并且作为工程的一部分,这个工程当然也包含了你自己的项目。由于这里这里的原因,我们推荐将Pods里面的内容也提交到版本库里面,而不是在每次新的代码签出后依赖于开发人员执行pod install

这里的原因大概可以这么来解释,通过将Pods文件夹加入版本库。当有新的开发人员克隆版本库的时候,只需要编译运行项目,不需要运行pod install这种需要长时间命令

注意从现在开始,你需要打开.xcworkspace文件,而不是.xcproject文件,否则代码将无法编译。

1
pod update

上面的命令将会更新所有的pods到Podfile文件上所允许的最新的版本。你可以使用运算符来指明你想要的版本。

Carthage

Carthage 采用简约而不简单的方式将你所依赖的代码打包成二进制库文件,而不是以神奇地将它们以各种方式集成到你的项目中。这会大大的减少编译时间,因为你的依赖在项目开始构建的时候就已经被编译好了。
由于没有集中式的项目仓库,这意味任何可以编译成框架的代码库都支持开箱即用的Carthage
要开始引入Carthage到你的项目中的话,请遵循Carthage文档中的说明

项目结构

为了避免将数以百计的源文件放置在同一个目录下,最好根据项目自身的架构设置一些文件夹结构层级。例如,你可以使用如下的划分方式:

1
2
3
4
5
├─ Models
├─ Views
├─ Controllers (或者是ViewModels, 如果你的项目是MVVM架构)
├─ Stores
├─ Helpers

首先,在 Xcode 的项目导航器中的项目名称目录下创建组(黄色的小文件夹),然后,对于每个组,通过点击 Xcode 的文件检查器下的灰色文件夹小图标,来到分组对应的真实物理路径,并创建对应名称的文件夹,并与 Xcode 中的组相关联。

本地化

项目伊始将所有的字符串都存储到本地化文件,不仅为翻译提供了便利,同时为快速查找字符串提供了便利。你可以在build scheme中加入启动参数来指定app的语言:

1
-AppleLanguages (Finnish)

而对于更加复杂的翻译场景,如取决于数量的复数形式(例如: “1 person” vs “3 people”),你应该使用.stringsdict格式文件而不是常规的格式化字符串文件。一旦你将视线转移到这个疯狂的语法上,你就拥有了一个知道如何为 onesomefewmany 应用复数化的强大工具,例如在俄语和阿拉伯语中

常量

保持常量的作用域尽可能的小,例如,当你只需要在一个类中使用常量的时候,那么这个常量作用域应仅限于这个类。需要在全局作用域保存的常量应当统一存放在一个地方。在Swift中,你可以使用枚举来定义常量然后生成Constants.swift文件来组织、存储和获取全局作用域的常量,这是一种非常干净的方式。

1
2
3
4
5
6
7
8
9
10
11
12
13
enum Config {
static let baseURL = NSURL(string: "http://www.example.org/")!
static let splineReticulatorName = "foobar"
}

enum Color {
static let primaryColor = UIColor(red: 0.22, green: 0.58, blue: 0.29, alpha: 1.0)
static let secondaryColor = UIColor.lightGray

// A visual way to define colours within code files is to use #colorLiteral
// This syntax will present you with colour picker component right on the code line
static let tertiaryColor = #colorLiteral(red: 0.22, green: 0.58, blue: 0.29, alpha: 1.0)
}

当你使用Objective-C时,将全局作用域常量存储在Constant.h文件中,该文件是被Prefix Header头文件所引用了的。
通过静态常量来代替预处理宏定义常量:

1
2
static CGFloat const XYZBrandingFontSizeSmall = 12.0f;
static NSString * const XYZAwesomenessDeliveredNotificationName = @"foo";

静态常量是类型安全的,有着更加显式的作用域(在未定义之前,它们不能在所有导入/包含的文件中使用),在后续开发中不能被重定义或者未定义,并且是在调试器中可用的。

分支模型

特别是在向公众发布应用程序时(例如通过 App Store),使用适当的标签将发布版本与其他分支隔离是一个好主意。此外,涉及大量提交的新特性开发工作应该在它自己的分支上完成。git-flow是一个可以帮助你遵循这些约定的工具。它只是Git分支和标签命令的一个便捷的封装,但能帮助团队或个人维护一个适当的分支结构。
所有的开发都是基于feature分支(或针对较小的工作基于Dev分支)、基于app版本的标签的发布以及提交都要通过下列代码:

1
git flow release finish <version>

最小的iOS兼容版本

尽早的决定你的项目所支持的最小iOS版本是十分有用的:明确需要基于哪个系统版本进行开发,测试以及哪些系统API可以使用可以帮助你评估工作量,并让你知道哪些是可用的,哪些是不安全的。

利用这些资源所收集的资料做出选择: