Workspace(工作区)
-
Workspace 简介(苹果开发者文档)
Workspace 用于对 Project 和其他文档进行分组,让开发者可以方便地一起处理他们。一个 Workspace 可以包含任意数量的 Project 以及你想要包含的其他任何文件。除了组织每个 Project 中的所有文件外,Workspace 还提供了所包含的 Project 及其 Target 之间的隐式和显式的关系
Workspace 扩展了工作流程的范围
一个 Project(项目文件)包含了:
① 指向项目中所有文件的指针
② 构建配置(Bulid Settings)
③ 其他项目信息在 XCode 3 和更早的版本中,Project 是分组和文件层次结构的根。虽然一个 Project 中可以包含对其他 Project 的引用,但是在 XCode 3 中处理相互关联的 Project 是复杂的。大多数工作流程仅限于单个 Project。在 XCode 4 及更高的版本中,可以选择创建一个 Workspace,来保存一个或多个 Project,以及希望包含的任何其他文件
Workspace 除了提供对每个包含的 Project 中的所有文件的访问权限之外,还扩展了许多 XCode 重要工作流程的范围。例如:
① 因为 XCode 的索引范围是整个 Workspace,所以 代码补全、跳转到定义 等内容感知的相关特性可以在 Workspace 的所有 Project 中无缝地工作
② 因为代码重构操作会作用于 Workspace 中的所有内容,所以可以仅通过一次操作就重构一个 Framework Project 的 API
③ 在构建(Build)时,一个 Project 可以使用同一个 Workspace 中的其他 Project 的 ProductWorkspace(工作区文件)除了包含指向其所包含的所有 Project 和文件的指针外,没有再包含其他数据
因此,一个 Project 可以属于多个 WorkspaceWorkspace 中的 Project 共享构建目录
默认情况下,Workspace 中的所有 Project 都构建在同一个目录中,此目录称为 The Workspace Build Directory(工作区构建目录)。每个 Workspace 都有自己的工作区构建目录。因为 Workspace 中,所有 Project 的所有 Product 都在同一个目录中构建,所以工作区构建目录中的所有文件对每个 Project 都是可见的。因此,如果有多个 Project 使用相同的库,则无需将库分别复制到每个 Project 的文件夹中
XCode 会检查工作区构建目录中的文件以发现隐式的依赖。例如:
Workspace 中的 Project A 构建了一个 Library A,Library A 被 Project B 引用,则 XCode 在构建 Project B 前会自动构建 Library A,即使构建配置(Build Settings)中没有明确地指定该依赖关系。如果必要的话,可以使用显示构建配置来覆盖这种隐式构建依赖。对于显式依赖,则必须创建 Project 的引用位于 Workspace 中的每个 Project 都保持自己的独立标识。Workspace 不会影响 Project,位于同一个 Workspace 中的 Project 也不会相互影响。可以在不打开 Workspace 的情况下打开 Project,也可以将 Project 添加到其他的 Workspace。因为一个 Project 可以属于多个 Workspace,所以开发者可以用多种组合方式处理 Project,而不必重新配置任何 Project 或者 Workspace
开发者可以使用默认的工作区构建目录,也可以自己指定一个。需要注意的是,如果 Project 指定了构建目录,则所有引用该 Project 的 Workspace 在构建时,都会将该 Project 的构建结果覆盖到指定的构建目录下
-
Workspace 使用
-
新建 Workspace
通过 XCode - File - New - Workspace,可以新建一个空的 Workspace
-
向 Workspace 中添加 Project 的两种方式:
① 在 Workspace 中,通过 File - Add Files to (Workspace 名称),向 Workspace 中添加一个已存在的 Project
② 在 Workspace 中,通过 File - New - Project,向 Workspace 中添加一个空的 Project
-
cocoaPods 就是使用了 Workspace 将开发工程与 Framework 进行了分层管理
Project(项目)
-
Project 简介(苹果开发者文档)
Project 是一个包含构建 Product(软件产品)所需的所有文件、资源和信息的仓库。Project 包含用于构建 Product 的所有元素,并维护这些元素之间的关系。一个 Project 可以包含一个或多个 Product,每个 Product 都有一个 Target 用于指定如何构建该 Product。Project 为其包含的所有 Target 定义默认的 Build Settings(Target 会继承 Project 的 Build Settings,开发者可以根据实际 Product 的需求,修改相应 Target 的 Build Settings)
Project(项目文件)包含以下内容: 1. 对源文件的引用 1.1 源代码(包括头文件和实现文件) 1.2 (内部或者外部的)Library 和 Framework 1.3 资源文件 1.4 图片文件 1.5 Interface Builder(界面生成器)的 nib 文件 2. 用于组织源文件的各种组(Groups)(在 XCode 界面的各个 Navigator 中) 3. 项目级的构建设置(Project-Level Build Settings)。 可以为一个 Project 指定多个构建设置(例如,可以为 Debug 和 Release 分别指定构建设置) 4. Targets(目标),其中每个 Target 都可以指定: 4.1 该 Target 所对应的 Product 4.2 构建该 Product 所需要的源文件 4.3 用于构建 Product 的构建设置(Build Settings),包括对其他 Target 的依赖 等 (除非开发者手动修改,否则 Target 将应用 Project 默认的 Build Settings) 5. 用于调试或测试程序的可执行环境,其中每个可执行环境都可以指定: 5.1 XCode 运行或者调试时要启动的可执行文件 5.2 要传递给可执行文件的命令行参数(如果有的话) 5.3 程序运行时所需的环境变量(如果有的话)
Project 可以单独存在,也可以包含在 Workspace 中
可以使用 Schemes(构建方案)来指定在给定时间,处于活动状态的 Target(目标),Build Configuration(构建配置),Executable Configuration(可执行文件配置)
-
Project 使用
-
在使用 XCode 创建 Project 时,会默认选中:
① Include Unit Tests(单元测试)
② Include UI Tests(UI 测试) -
Project 创建成功后,可以在左侧的 Project Navigator 导航栏里面看到有 4 个文件夹,分别为:
① Demo 文件夹(Demo 为工程名称)
② DemoTests 文件夹(用于 Demo 的单元测试)
③ DemoUITests 文件夹(用于 Demo 的 UI 测试)
④ Products 文件夹(用于保存工程输出的 Product)对于 Demo 文件夹、DemoTests 文件夹、DemoUITests 文件夹:
① 每个文件夹都对应一个 Target
② 每个文件夹都对应 Products 文件夹下的一个 Product
③ 每个文件夹都是真实的物理文件夹(而 Products 文件夹则是虚拟的逻辑文件夹)
④ 每个文件夹里面都有一个 Info.plist 文件(这也说明了 Project 下的每个 Target 是独立管理的)并且,由下图可以看出:
一个 Project 可以包含一个或多个 Target
一个 Target 对应一个 Product
-
Project 的设置选项卡有以下 3 个:
① Info(项目信息)
Deployment Target:用于设置 Project 下所有 Target 默认支持的最低 iOS 版本
Configurations:用于设置 Project 下所有 Target 默认可用的编译配置
Localizations:设置应用的本地化语言
② Build Settings(构建设置)
Project 的构建设置和 Target 的构建设置基本相同
可以在这里定义所有 Target 默认的构建设置
③ Swift Packages(Swift 包管理)
-
Target 的 Info 和 Build Settings 会继承 Project 的 Info 和 Build Settings
由下图可以看出:Target 的设置选项卡要比 Project 的设置项卡多得多
Target(目标对象)
-
Target 简介(苹果开发者文档)
Target 用于指定要构建的 Product,并且包含从 Workspace 或者 Project 的一组文件集合中构建 Product 的说明。一个 Target 定义一个 Product。Target 将输入数据组织到构建系统中(输入数据指的是构建该 Product 所需的源文件和处理这些源文件的说明)。一个 Project 可以包含一个或多个 Target,每个 Target 用于生产一个 Product
构建 Product 的说明,采用 Build Settings 和 Build Phases 的形式给出,开发者可以在 XCode 项目编辑器中进行检查和编辑。Tartet 会继承 Project 的 Build Settings,但是开发者可以通过在 Target 级别指定不同的 Build Settings 来覆盖任何从 Project 继承的 Build Settings。一次只能有一个 Target 处于活动状态,通过 Scheme 指定处于活动状态的 Target
一个 Target 及其创建的 Product 可以与另一个 Target 相关。如果 Target A 需要 Target B 的输出才能构建,则称 Target A 依赖于 Target B。如果 Target A 和 Target B 在同一个 Workspace 中,则 XCode 可以自己发现依赖关系,在这种情况下,XCode 将按所需顺序构建 Product,这种关系被称为隐式依赖。开发者可以在 Build Settings 中显式指定 Target 的依赖关系,并且还可以指定 XCode 可能期望具有隐式依赖关系的两个 Target 实际上是不依赖的。例如,开发者可能会在同一个 Workspace 中构建一个库和一个使用该库的应用程序。XCode 可以发现这种关系并首先自动构建该库。但是,如果开发者实际上要链接到应用程序上的库的版本不是 Workspace 中内置的这个库,则可以在 Build Settings 中创建一个显式的依赖项来明确指定应用程序对库的引用关系,该显式依赖项将覆盖此隐式依赖项
-
Target 的作用
在 iOS 开发中,对于同一个项目(Project),可能会有不同的版本,如完整版和删减版,App Store 版和企业版,这些版本之间大部分是相同的,只是小部分有些差异(例如:代码基本相同,但是编译设置以及包含的资源文件不同)。在这种情况下,调试和发布时,需要不停的修改编译参数和资源文件的引用,比较繁琐。于是,XCode 提供了一些途径用来管理这些有着细微差别的版本,这就是 Target
Target 可以看作是工程(Project)的输出目标配置列表,它保存着当前工程的所有设置,可以通过它来管理项目的版本。在每个 Target 中,可以添加不同的源代码文件和资源文件(这些源代码文件和资源文件都来自 Target 所属的 Project),并且使用一个独立的 Info.plist 文件,以构建不同的 Product。即,Target 用于同一个 Project 的不同分配
Target 代表着通过 XCode 构建出来的一个最终产品,它可能是一个 App,一个 Framework、或者一个 Tests 包。无论如何,一个 Target 通常对应 Products 文件夹下面的一个产品
-
Target 选项卡介绍
① General(通用)
Identity:设置应用的身份标识信息 Deployment Info:设置应用的部署信息 App Icons and Launch Images:设置应用图标和启动页图片 Frameworks,Libraries,and Embedded Content:设置应用使用到的一些二进制库文件(系统的 + 第三方的) Development Assets:设置开发过程所需的一些资源
② Signing & Capabilities(签名和功能)
用于设置应用的签名信息 与 添加应用使用到的系统功能
③ Resource Tags(资源标签)
用于将资源放到 AppStore,在需要的时候再进行下载
④ Info(信息)Custom iOS Target Properties:自定义的 Target 属性,有很多关键字,请参考苹果官方文档 Document Types:定义了应用能够识别的文档类型,不需要识别文档的应用不用设置 Exported UTIs / Imported UTIs:导出/导入 统一类型标识符(Uniform Type Identifiers),UTIs 能让应用识别对应的文件类型 URL Types:用于应用间数据的交互,多用于应用间的跳转
⑤ Build Settings(构建设置)过滤栏设置: Basic:显示最常用的构建设置 Customized:显示自定义的构建设置 All:显示全部的构建设置 Combined:显示单个 Target 的构建设置 Levels:显示所有 Target 的构建设置 Add User-Defined Setting:添加用户自定义设置 由于具体的构建设置太多,且涉及很多底层知识,详细内容请参考苹果开发文档
⑥ Build Phases(构建阶段)Build Phases 用于控制 XCode 在通过 Target 构建 Product 的过程中,各个阶段的行为 通过 Build Phases 可以对 Target 的构建过程进行复杂和精确的控制 开发者可以定义和设置的构建阶段有以下 7 个: 1. Dependencies(XCode 默认):用于设置 Target 间的依赖关系。通过它可以让 XCode 知道在当前 Target 构建之前,必须预先构建哪些其他的 Target,该阶段无法删除 2. Compile Sources(XCode 默认):在此阶段中定义的代码源文件将参与 Target 的构建。可以通过修改代码源文件对应的 Compiler Flags 来为其设置编译器标识,比如设置代码源文件支持 MRC 3. Link Binary With Libraries(XCode 默认):通过此阶段设置需要参与链接的二进制文件和库文件。系统库不会出现在这里(因为系统库是动态库) 4. Copy Bundle Resources(XCode 默认):在此阶段中定义的资源文件,在 Target 构建时,将会被复制到 Product 的安装包里面 5. Headers:用于指定头文件的可见性,Public - 可见,Private - 不可见, Project - 构建 Target 时使用 6. Copy Files:在 Target 构建时,XCode 会把在此阶段定义的文件复制到 App 安装包内指定的路径下 7. Run Script:在此阶段定义当 Target 构建时,需要运行的脚本
⑦ Build Rules(构建规则)
用于定义文件类型以及用于编译它们的编译器之间的关联 -
使用 Target 进行版本控制
- 通过 XCode 提供的 iOS - Single View App 模板,创建一个 Demo 工程
工程创建完成后,在 TARGETS 下生成了 3 个 Target,分别是:
Demo(用于构建 Product)、DemoTests(用于单元测试)、DemoUITests(用于 UI 测试)
- 选中 Demo Target,右键 - Duplicate 进行复制,复制完成后,Project 中会新增以下 4 样东西:
① 复制出来的 Target,名称默认为 Demo copy
② 因为一个 Target 对应一个 Info.plist,所以在右侧的项目导航器(Project Navigator)中,会多出一个 Demo copy-Info.plist
③ 因为一个 Target 对应一个 Product,所以在右侧的项目导航器(Project Navigator)中,会多出一个 Demo copy.app
④ 因为 XCode 会为新增的 Target 创建默认的构建方案,所以在 Schemes 中,多出了一个名为 Demo copy 的构建方案
修改 Demo copy Target 的名称为 DemoLite,可以看到右侧的项目导航器(Project Navigator)中 Products 文件夹下 Demo copy.app 的名称也被同步修改为 DemoLite.app
修改 Demo copy-Info.plist 的名称为 DemoLite-Info.plist
然后到 TARGETS - DemoLite - Build Settings - Packaging - Info.plist File 中,更新 DemoLite Target 对于 Info.plist 的引用
- 因为 DemoLite Target 是从 Demo Target 复制而来,所以两个 Target 的所有配置是一样的(除了 Target Name 与 Info.plist)
又因为 Demo Target 与 DemoLite Target 代表着两个不同版本的产品,需要能同时安装到 iOS 设备上
所以需要修改 DemoLite Target 的 Bundle Identifier
- 为 Demo Target 与 DemoLite Target 添加用于区分完整版与 Lite 版的宏定义
宏定义到 Target - Build Settings - Preprocessing 中添加
对 Demo Target 添加宏定义:VERSION_NORMAL=1
对 DemoLite Target 添加宏定义:VERSION_LITE=1
- 在 ViewController.m 中,添加根据不同宏定义弹出不同提示的代码
- 在 Assets.xcassets 中,为 Demo Target 与 DemoLite Target 添加两套不同的 App 图标
并分别到 Target - General - App Icons and Launch Images 里面设置 Target 对图标资源的引用
- 分别选中两个 Target 对应的 Scheme 并运行到 iPhone 上
可以看到,在 iPhone 上分别安装了两个 Target 对应的不同的 Product(基于同一份代码),并且使用了不同的 App Icon(使用了不同的资源),有不同的提示(拥有不同的功能)
- 这里有个细节需要注意:
如果 Project 中有多个 Target,在添加源代码文件(或者其他资源文件)时,可以选择将文件添加到不同的 Target 中
如果某个 Target 需要特定的文件,则在添加该文件时,需要选择对应的 Target,否则,即使文件添加到了 Project 中,也没有添加到相应的 Target 中,那么 Target 在构建时,将会缺少对该文件的引用
我们也可以通过文件检查器(File Inspector)修改 Project 中已经存在的文件所对应的 Target
Build Settings(构建设置)
-
Build Settings 简介(苹果开发者文档)
Build Settings 是一组变量,该组变量包含有关该如何执行 Product 构建过程的特定方面的信息。例如,可以通过设置 Build Settings 来指定 XCode 将传递给编译器的选项
开发者可以在 Project 级别或者 Target 级别指定 Build Settings。每个 Project 级别的 Build Settings 都适用于 Project 中的所有 Target,除非被 Target 特定的 Build Settings 明确覆盖
每个 Target 都组织用于构建一个 Product 所需的源文件。Build Settings 指定一组用于以特定方式构建(Target 的)Product 的设置。例如,对于产品的调试和发布,通常有分开的 Build Settings
XCode 中的每个 Build Settings 包括两部分:标题和定义(类似于 Key-Value)
标题(Key)用于标识 Build Settings,并且可以在其他 Build Settings 中使用
定义(Value)是 XCode 在构建时用于确定构建设置值的常量或公式
Build Settings 也可能具有用于显示的名称,该名称用于在 XCode 的用户界面中显示构建设置除了 XCode 在从 Project 模板创建新 Project 时提供的默认 Build Settings 外,开发者还可以为 Project 或特定的 Target 创建用户自定义的 Build Settings。开发者还可以指定条件构建设置(Conditional Build Settings)。条件构建设置的值取决于是否满足一个或多个先决条件。 例如,该机制允许开发者基于 Target 的 Architecture 指定用于构建 Product 的 SDK
-
Build Settings 使用
Build Settings(构建设置)里面的很多内容涉及底层原理,详细的请参考苹果开发者文档
Scheme(构建方案)
-
Scheme 简介(苹果开发者文档)
Scheme 定义了要构建的 Target 的集合、构建时要使用的配置 以及 要执行的测试的集合
开发者可以定义多个 Scheme,但是一次只能运行一个。开发者可以指定 Scheme 是否存储在 Project 中,在这种情况下,Scheme 可以在包含该 Project 的所有 Workspace 中使用。或者开发者指定 Scheme 是否存储在 Workspace 中,在这种情况下,Scheme 仅在该 Workspace 中可用。当选中一个运行的 Scheme 时,同时也意味着选中了一个硬件体系架构(即,产品运行时使用的真机或者模拟器)
-
Scheme 使用
- Scheme 用于定义当按下 Build、Run、Test、Profile、Analyze 等时,会发生什么。即,Scheme 包含了构建 Target 时使用的构建设置 与 运行 Target 时使用的运行环境
- 点击 Manage Schemes… 可以进入 Scheme 的管理界面:
① AutoCreate schemes 复选框:表示创建 Target 时,是否为该 Target 自动创建构建方案
② AutoCreate Schemes Now 按钮:立即为当前 Target 创建默认的构建方案
③ Show 复选框(Show Schemes / Hide Schemes):显示或隐藏构建方案,用于指定在外部构建方案列表中显示的构建方案
④ Scheme:构建方案的名称
⑤ Container:用于存储构建方案的容器,可以是 Project 或者 Workspace
⑥ Shared 复选框(Share Schemes / Un-share Schemes):是否在团队成员间共享构建方案。独立开发无需关心该功能。在团队开发时,如果自己的构建方案不需要共享给其他人,取消勾选即可
⑦ + 与 - :新增或删除构建方案。需要注意的是
因为一个 Scheme 至少会包含一个 Target,所以在新增 Scheme 时,必须要指定该 Scheme 要绑定的 Target 对象
当删除 Scheme 时,Scheme 对应的 Target 不会被删除。同样地,当删除 Target 时,Target 对应的 Scheme 也不会被删除
⑧ Duplicate:复制构建方案
⑨ Import 与 Export:导入与导出构建方案
ps:通过拖动 Scheme 管理界面的构建方案 item,可以调整构建方案在外部列表中的显示顺序
- 通过 Scheme 管理界面下方的 Edit… 按钮可以进入单个构建方案的编辑界面
构建方案编辑界面右侧列出了一个构建方案可以执行的动作,包括:
① Build(构建),在执行其他动作前必须执行的动作,优先于其他动作(运行、测试、剖析、分析、打包)
② Run(运行),用于指定运行过程中需要的可执行文件、调试器、运行环境等选项
③ Test(测试),用于指定当前构建方案所使用的测试包(单元测试、UI 测试)
④ Profile(剖析),用于指定当使用剖析操作时,XCode 会执行何种命令
⑤ Analyze(分析),用于对指定的对象运行静态分析器
⑥ Archive(打包),用于在打包应用程序时进行一些个性化的设置
在这里可以编辑构建方案各个动作所对应的详细设置
其他
- 在 Build Settings 中定义预处理宏的三种方式:
① Target - Build Settings - Custom Compiler Flags - Other C Flags
② Target - Build Settings - Preprocessing - Preprocessor Macros
③ Target - Build Settings - Packaging - Info.plist Preprocessor Definitions