Carthage
Carthage 是一个较新的 Cocoa 开发第三方套件管理工具,相较于知名 CocoaPods 管理工具的複杂配置,轻巧的 Carthage 在推出之后广受 Swift 社群喜爱。
本文基于 Carthage 0.20: Unary, Binary, Ternary
特色
- 时代潮流:Written in Swift! (v.s. CocoaPods in Ruby)
- 主流现代:iOS 8+, dynamic framework only
- 去中心化:无提供类似 cocoapods、npm 这种中心储存库。
- 非入侵式:不会修改 Xcode 相关配置,耦合性低。
快速上手
- 从终端环境安装 Carthage
brew install carthage
如果还没有装 homebrew,请来这下载
- 建立一个
Carfile
,列出欲使用的模组,例如:
github "Alamofire/Alamofire" ~> 4.4
github "ReactiveX/RxSwift" ~> 3.0
- 在终端环境输入
carthage update
,Carthage 将自动下载所有相依模组至Carthage/Checkouts
资料夹中,并编译成 frameworks(或直接下载 pre-compiled framework)。 - 将
Carthage/Build
资料夹内编译好的 frameworks 拖拉进你的 app target => General => Linked Frameworks and Libraries - 在 app target => Build Phases 下新增一个 New Run Script Phase
# 自动将 framework 複製到 target app 的 bundle中
/usr/local/bin/carthage copy-frameworks
并在 Input Files 加入相依的 frameworks 路径,例如:
$(SRCROOT)/Carthage/Build/iOS/Alamofire.framework
$(SRCROOT)/Carthage/Build/iOS/RxSwift.framework
Cartfile 版号语法简介
Cartfile 版号语法与 Podfile 雷同:
# 版号 >= 3.1.2
github "ReactiveX/RxSwift" >= 3.1.2
# 版号 3.x (3.0 <= ver < 4.0)
github "SnapKit/SnapKit" ~> 3.0
# 仅匹配版号 0.4.1
github "jspahrsummers/libextobjc" == 0.4.1
# 最新版
github "jspahrsummers/xcconfigs"
# 指定 Git branch
github "jspahrsummers/xcconfigs" "branch"
# 其他 Git Server Repository 的 develop 分支
git "https://agitserver.com/swift-test/swift-test.git" "develop"
# 本地 local Git Repository
git "file:///directory/to/project" "branch"
常见议题
Q:Carthage 资料夹裡面究竟有啥?
Carthage/
├── Build/
│ ├── iOS/
│ │ ├── Alamofire.framework
│ │ ├── Alamofire.framework.dSYM
│ │ ├── SnapKit.framework
│ │ └── SnapKit.framework.dSYM
│ └── macOS/
│ └── ... macOS 等其他平台 的 framework
└── Checkouts/
├── Alamofire/
│ ├── ... Alamofire clone 下来的原始码
└── SnapKit/
└── ... SnapKit clone 下来的原始码
- Carthage/Build: 打包好的 framework(pre-built 或是从 checkouts build 出来的)
- Carthage/Checkouts: 所有相依模组的 source code
Q:如何避免 carthage udpate
取得的模组版号不同?
Carthage 提供一个锁定文件 Cartfile.resolved
,记录了当前被确切安装的模组精确版号。每次更动新增相依模组时,Cartfile.resolved
即会自动更新。可预防部分模组版号没有完全遵循 语意化版本(SEMVER) 时产生的问题。
建议将 Cartfile.resolved
提交至版本管理系统中。之后将远端储存库 clone 下来,只需要执行
carthage bootstrap
就可以取得与提交时版号完全相同的模组了。
Q:我不想提交 Carthage 资料夹到 Git Server,怎办?
一般而言,我们会将 Carthage 加入 Project 的 .gitignore
中:
# within .gitignore
Carthage
除非另有需求,不然 Cartfile.resolve
应足以还原 project 与提交时相同版号的模组环境。
Q:我需要开发用但非 Project 相关的模组,该如何?
Carthage 提供另一个 Cartfile.private
,配置方法与 Cartfile
相同。Cartfile.private
内的相依模组不会被作为主模组的 dependency。可用来配置开发用模组,譬如使用 testing framework。
Q:如何只提供 binary framework,不开放 source code?
Carthage 提供的来源除了 Git 以外,事实上最近才提供 binary 这个选项。
Cartfile 范例如下:
binary "https://example.com/release/ExampleFramework.json" ~> 1.4.0
这裡的 json 档应描述该 framework 对应版号的下载路径,配置范例如下:
{
"1.3.5": "https://example.com/release/1.3.5/framework.zip",
"1.4.3": "https://example.com/release/1.4.3/framework.tar.gz"
}
除此之外,目前只接受 https
url 连结,且 version 只能对应语意化版本, Git branch/tag/commit 都暂时无法使用。
Q:如何同时修改相依模组的 code,并在 Run 时同步更新吗?
可以,请新增一个 Run Script build phase,在 Run App 后会自动 build 新的 framework:
/usr/local/bin/carthage build --platform "$PLATFORM_NAME" --project-directory "$SRCROOT"
!!!!!注意!!!!!
所有在 Carthage/checkouts 内的 source 随时可能改变。如果确定需要改动相依模组,请利用 carthage 指令将相依模组加入 Git submodules。
carthage update --use-submodules
# or
carthage checkout --use-submodules
之后就可以直接操作 Git submodules 了!