Carthage 新手教程
Carthage 与 Cocoapods 的不同
Cocoapods 是由来已久的 Cocoa 依赖管理工具,那么为什么 Carthage 项目被创建?
首先,Cocoapods(默认情况下)会自动的为你的应用程序和所有依赖创建和更新 Xcode workspace。Carthage 用 xcodebuild 构建框架(framework)的二进制文件,但是并没有将他们整合到用户项目中。Cocoapods 的目的是让用户使用起来更简单,而 Carthage 则是更灵活,减少对项目的侵入性。
Cocoapods 的目标在其README文件中有如下描述:
… to improve discoverability of, and engagement in, third party open-source libraries, by creating a more centralized ecosystem.
对比之下,Carthage 被创建成一个松散(decentralized)的依赖管理者,没有中心项目清单,这减少了维护工作并避免了任何中心故障点(通俗的讲就是去中心化)。然而,项目被发现就变的更加困难 – 用户必须去使用 GitHub 的 Trending 页面或者其他类似的页面(Cocoapods 就比较简单的可以在终端搜索需要使用的库)。
Cocoapods 项目还必须具有所谓的 podspec 文件,其中包括有关项目的元数据,并指定应如何构建它。Carthage 使用 xcodebuild 去构建依赖,而不是将它们集成到单个工作区中,它没有类似的规范文件,但你的依赖项必须包含到自己的 Xcode 项目中,该项目描述了如何构建其产品。
最终,我们创建了 Carthage,因为我们想要一个最简单的工具 – 一个可以完成工作而不必承担 Xcode 责任的依赖管理器,并且并没有为框架作者创造额外的工作。Cocoapods 提供了许多惊人的功能,但是在 Carthage 中,这些功能永远不会出现,因为这会增加额外的复杂性。
Carthage 安装
使用 homebrew 安装
1  | brew install carthage  | 
查看版本和升级
1  | // 查看版本:  | 
卸载
1  | brew uninstall carthage  | 
Carthage 配置第三方库(iOS,tvOS,watchOS)
创建 Cartfile 文件
1  | cd to your project  | 
用 Xcode 打开/编辑 Cartfile
1  | open -a Xcode Cartfile  | 
添加依赖库
1  | github "Alamofire/Alamofire" == 4.5  | 
现在支持的三个来源是 GitHub 存储库,Git 存储库和通过 https 提供的仅二进制框架。未来可能会添加其他可能的来源。如果你想看到具体的东西,请提 issue。
GitHub Repositories
使用 github 关键字指定 GitHub 存储库(GitHub.com 和 GitHub Enterprise):
1  | github "ReactiveCocoa/ReactiveCocoa" # GitHub.com  | 
github 源是用于 owner/repo 表单指定或通过其 web API 使用预构建的二进制下载功能,因此对 github 源 使用 git 或 ssh 协议是没有意义的,并且这是一个错误。
Git repositories
其他 Git 存储库使用 git 关键字指定:
1  | git "https://enterprise.local/desktop/git-error-translations2.git"  | 
Binary only frameworks
仅作为已编译的二进制文件 .frameworks 提供的依赖项使用 binary 关键字和 https:// 链接,file:// 链接,或没有方案的相对或绝对路径,返回二进制项目规范:
1  | binary "https://my.domain.com/release/MyFramework.json" // Remote Hosted  | 
版本要求
Carthage 支持多种版本要求:
>= 1.0指“1.0 及以上版本”。~> 1.0指“1.x 版本”== 1.0指“版本为 1.0”"some-branch-or-tag-or-commit"特指git对象(git rev-parse任何内容都被允许)。- Note:
二进制源不支持这种形式。 
- Note:
 
如果没有指定任何版本,任何版本的依赖都将被允许(默认使用最新版本)。
Example Cartfile
1  | # Require version 2.3.1 or later  | 
安装/编辑 Cartfile 中的项目
clone 项目,然后编译成 framework:
1  | // 不指定 platform 会为所有的平台编译(Mac / iOS / tvOS / watchOS)  | 
Cartfile 利用 xcode-select 命令来编译 framework,如果你想用其他版的 Xcode 进行编译,执行下面这条命令,把 xcode-select 的路径改为另一版本 Xcode 就可以。 
1  | sudo xcode-select -s /Applications/Xcode-beta.app/Contents/Developer  | 
所有的文件会被编译到当前路径的 Carthage 文件夹中:
1  | // 打开文件夹  | 
Carthage 文件夹中文件说明:

Cartfile.resolved
运行 carthage update --platform iOS 命令后,一个叫 Cartfile.resolved 的文件将会被创建到 Cartfile 同级目录下。此文件准确指定了每个依赖项选择的版本,并列出了所有依赖项(甚至是嵌套的版本)。
强烈建议将该文件加入到版本控制中,告知其他开发者,当前使用的版本。
虽然 Cartfile.resolved 文件是人类可读和可扩展的,但你不能修改它。文件的格式非常严格,列出依赖项的顺序对于构建过程很重要。
Carthage 文件夹
- Build
包含对应平台编译好的Framework - Checkouts
包含编译framework所使用的源代码(除非你使用 submodules ,否则不要修改这里的代码,carthage update和carthage checkout会覆盖这里的代码,清除你的修改)。 
With submodules
如果在引导项目的依赖项时给出了 --use-submodules 标志,updated 或者 checked out Carthage/Checkouts 中的依赖项将作为 Git 子模块(submodules)提供。这允许你对依赖项进行更改,并提交这些更改。
更新Framework的版本
打开 Cartfile
1  | open -a Xcode Cartfile  | 
修改版本
1  | // github "Alamofire/Alamofire" == 4.5  | 
更新
1  | carthage update --platform iOS  | 
更新指定库
1  | carthage update SVProgressHUD --platform iOS  | 
引入 Carthage 依赖库到 Xcode
- 在 
Carthage -> Build中找到需要添加的framework。 - 拖拽对应的 
framework到 Xcode 工程的Linked Frameworks and Libraries中。 

- 进入工程的 
target -> Build Phases,点击+,添加New Run Script Phase: 

添加如下脚本命令:
1  | /usr/local/bin/carthage copy-frameworks  | 
在 Input Files 下添加要使用的框架的路径。例如:
1  | $(SRCROOT)/Carthage/Build/iOS/Alamofire.framework  | 
将复制框架的路径添加到 Output Files。例如:
1  | $(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/Alamofire.framework  | 
为什么需要指定 Output Files。
使用 Carthage 来管理第三方库,在编译并运行 App 的时候,会有一个阶段叫:Carthage Copy Frameworks。这个阶段通过跑一个脚本的形式把所有依赖的第三方库都复制到 App 的目录里。
这个阶段通常会花 1~x 秒不等,这取决于你的 App 依赖的第三方库数量。默认情况下,每次你 Build & Run 的时候,都会进行一次这个操作——尽管你的第三方库没有任何改变。
所以我们需要指定 Output Files,在 Output Files 指定输出文件的情况下,Xcode 只会在 framework 发生更改时去进行 copy framework 操作,这样就节省了时间。