Table of contents
Open Table of contents
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 安装
brew install carthage
查看版本和升级
// 查看版本:
carthage version
// 升级:
brew upgrade carthage
卸载
brew uninstall carthage
Carthage 配置第三方库(iOS,tvOS,watchOS)
创建 Cartfile 文件
cd to your project
touch Cartfile
用 Xcode 打开/编辑 Cartfile
open -a Xcode Cartfile
添加依赖库
github "Alamofire/Alamofire" == 4.5
github "Alamofire/AlamofireImage" ~> 3.2
现在支持的三个来源是 GitHub 存储库,Git 存储库和通过 https 提供的仅二进制框架。未来可能会添加其他可能的来源。如果你想看到具体的东西,请提 issue。
GitHub Repositories
使用 github 关键字指定 GitHub 存储库(GitHub.com 和 GitHub Enterprise):
github "ReactiveCocoa/ReactiveCocoa" # GitHub.com
github "https://enterprise.local/ghe/desktop/git-error-translations" # GitHub Enterprise
github 源是用于 owner/repo 表单指定或通过其 web API 使用预构建的二进制下载功能,因此对 github 源 使用 git 或 ssh 协议是没有意义的,并且这是一个错误。
Git repositories
其他 Git 存储库使用 git 关键字指定:
git "https://enterprise.local/desktop/git-error-translations2.git"
Binary only frameworks
仅作为已编译的二进制文件 .frameworks 提供的依赖项使用 binary 关键字和 https:// 链接,file:// 链接,或没有方案的相对或绝对路径,返回二进制项目规范:
binary "https://my.domain.com/release/MyFramework.json" // Remote Hosted
binary "file:///some/Path/MyFramework.json" // Locally hosted at file path
binary "relative/path/MyFramework.json" // Locally hosted at relative path to CWD
binary "/absolute/path/MyFramework.json" // Locally hosted at absolute path
版本要求
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
# Require version 2.3.1 or later
github "ReactiveCocoa/ReactiveCocoa" >= 2.3.1
# Require version 1.x
github "Mantle/Mantle" ~> 1.0 # (1.0 or later, but less than 2.0)
# Require exactly version 0.4.1
github "jspahrsummers/libextobjc" == 0.4.1
# Use the latest version
github "jspahrsummers/xcconfigs"
# Use the branch
github "jspahrsummers/xcconfigs" "branch"
# Use a project from GitHub Enterprise
github "https://enterprise.local/ghe/desktop/git-error-translations"
# Use a project from any arbitrary server, on the "development" branch
git "https://enterprise.local/desktop/git-error-translations2.git" "development"
# Use a local project
git "file:///directory/to/project" "branch"
# A binary only framework
binary "https://my.domain.com/release/MyFramework.json" ~> 2.3
# A binary only framework via file: url
binary "file:///some/local/path/MyFramework.json" ~> 2.3
# A binary only framework via local relative path from Current Working Directory to binary project specification
binary "relative/path/MyFramework.json" ~> 2.3
# A binary only framework via absolute path to binary project specification
binary "/absolute/path/MyFramework.json" ~> 2.3
安装/编辑 Cartfile 中的项目
clone 项目,然后编译成 framework:
// 不指定 platform 会为所有的平台编译(Mac / iOS / tvOS / watchOS)
// 查看更多关于 update 命令的选项:`carthage help update`
carthage update --platform iOS
Cartfile 利用 xcode-select 命令来编译 framework,如果你想用其他版的 Xcode 进行编译,执行下面这条命令,把 xcode-select 的路径改为另一版本 Xcode 就可以。
sudo xcode-select -s /Applications/Xcode-beta.app/Contents/Developer
所有的文件会被编译到当前路径的 Carthage 文件夹中:
// 打开文件夹
open Carthage
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
open -a Xcode Cartfile
修改版本
// github "Alamofire/Alamofire" == 4.5
github "Alamofire/Alamofire" ~> 4.5.0
更新
carthage update --platform iOS
更新指定库
carthage update SVProgressHUD --platform iOS
引入 Carthage 依赖库到 Xcode
- 在
Carthage -> Build中找到需要添加的framework。 - 拖拽对应的
framework到 Xcode 工程的Linked Frameworks and Libraries中。

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

添加如下脚本命令:
/usr/local/bin/carthage copy-frameworks
在 Input Files 下添加要使用的框架的路径。例如:
$(SRCROOT)/Carthage/Build/iOS/Alamofire.framework
将复制框架的路径添加到 Output Files。例如:
$(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 操作,这样就节省了时间。