上篇博客詳細的聊了CocoaPods的相關內容,今天我們就來介紹另一個Cocoa的包管理器Carthage。在上家公司用Swift開發工程時,用的就是Carthage。Carthage誕生於14年11月份,是用Swift語言開發的,相對於CocoaPods來說是一個新生事物。本篇博客主要介紹一下Carthage的使用姿勢,接下來幾篇博客會介紹一下Carthage的源代碼,看一下其工作原理。本篇博客我們會先介紹Carthage的按照和使用,然后再看一下Carthage額工作原理,然后再將自己的庫關聯到Carthage,最后來對比一下CocoaPods。
首先我們來看一下Carthage的官方介紹:Carthage的初衷是以最簡單的方式來為你的Cocoa應用添加framework。Carthage將你依賴的三方庫編譯成二進制的framework,然后再提供給你使用。但是對你的工程結構有着完整的控制權。Carthage不會自動的修改你的工程文件或者編譯設置。
Carthage is intended to be the simplest way to add frameworks to your Cocoa application.Carthage builds your dependencies and provides you with binary frameworks, but you retain full control over your project structure and setup. Carthage does not automatically modify your project files or your build settings.
一、Carthage的安裝和使用
1、Carthage的安裝
Carthage的安裝是比較簡單的,通過brew就可以直接安裝,命令如下:
brew install carthage
2、Carthage的使用-carthage update
Carthage中管理依賴的文件為Carfile,我們可以創建一個名為Cartfile的文件來容納我們工程中所依賴的三方庫。如下所示下方的Cartfile中依賴了一個AFNetWorking庫和一個並沒有支持Carthage的私有庫。在Cartfile文件中,我們以github來直接指定該庫在github上的域名path。添加完Cartfile文件后,接下來我們通過下方的命令進行安裝即可。
carthage update
在執行上述命令時我們看到,對於“MyCocoaPodsTestProject”這個依賴倉庫提示“該倉庫沒有被分享的framework schemes”, 稍后我們將會對“MyCocoaPodsTestProject”這個倉庫添加shared framerwork schemes。
執行完carthage update命令后,會生成一個Cartfile.resoved的文件和一個Carthage的文件夾。這個.resolved的文件與CocoaPods中的lock文件功能一致,都是用來鎖版本的。而這個Carthage文件夾下存放的就是Carthage為我們提供的動態庫framework。
3、工程中引入framework
接下來要做的就是把Carthage生成的相應依賴庫的framework引入到我們的工程中。首先找到我們工程對應的Targets, 然后找到Build Phases下方的 ➕號下方的New Run Script Phase, 來添加引入framework的相關腳本。
下方是剛剛添加的Run Script,稍后會進行配置。
在Shell下方配置上carthage的命令路徑以及相關的運行命令的參數,如下所示:
/usr/local/bin/carthage copy-frameworks
配置完相關的運行腳本后,在Link Binary With Libraries中添加或者拖入生成的三方庫即可。
拖入完畢后,接下來我們就可以直接使用了。
二、自己的倉庫關聯Carthage
從上面Carthage update時提示的錯誤我們不難發現要想支持Carthage, 我們的git倉庫中必須有一個可以生成framework的Project,並且該Project開啟了Scheme的分享功能。接下來我們就讓上述的 MyCocoaPodsTestProject工程支持Carthage的update。
1、創建 framework project
首先在我們工程所對應的github目錄下方創建一個Cocoa Touche Framework的工程。如下所示:
2、引入源代碼
然后在這個framework工程中引入相關的源文件。
在引入相關的源文件后,在Build Phasea中的Header中的Public中添加對外暴露的頭文件,如下所示:
在相關的.h文件中引入該framework所提供的相關頭文件,此處類似pch文件的設置。
如果你創建的framework的Project的名字與你預期的不同,可以在Build Settings中的Product Name中進行設置,如下所示:
2、shared schemes
接下來就該設置Scheme的Share了,首先打開Manager Schemes…如下所示:
然后在Shared后方打鈎即可。
3、framework的編譯
使用終端進入到該工程目錄中,使用carthage進行編譯:
carthage build -no-skip-current
在我編譯的時候遇到了上述的錯誤,不過Carthage的github主頁給出了相關的解決方案,即使用xcodebuild進行編譯,如下所示:
使用上述命令編譯 結果如下所示:
使用xcodebuild編譯后,我們又使用carhage build --no-skip-current試了一次,可以正常編譯
進行編譯后,創建相關的tag然后push到遠端即可。
然后我們就可以在Carthage中正常使用我們的庫了。
在引用相關庫的時候需要添加上其庫名,如下所示:
三、carthage編譯
因為Carthage工程是Swift編寫的,並且是使用Carthage進行的依賴管理。 我們可以從github上Clone相關的代碼,然后執行carthage update進行依賴庫的加載,如下所示:
加載完畢后,我們就可以正常編譯運行了,下篇博客會介紹Chathage的相關源代碼的設計結構。
四、Carthage VS CocoaPods
兩者各有各的好處,也各有各的缺點,下方是Carthage的README中給出的與CocoaPods的不同之處。
下邊是根據上面的英文自己翻譯了一下:
CocoaPods是一個長期在Cocoa項目中使用的包管理工具,但為什么還要去創建一個Carthage呢?
首先,CocoaPods默認是會為你的工程自動創建和更新一個Xcode工作空間,並且還會創建和更新所有的依賴(備注:安裝pod后會創建一個xxxxxx.xcworkspec的文件,通過該文件可以打開Xcode工作空間,該工作空間除了你自己的project外,在Pods中還會引入其依賴的三方庫的源代碼)。而Carthage與其不同,其會使用xcodebuild工具將依賴的庫編譯成二進制的framework, 但是整合這個framework的責任就落到了用戶的身上。浸入式的CocoaPods使用起來會更為容易一些,而非浸入式的Carthage使用起來則更為靈活。
下方是CocoaPods的README中列舉的目標之一:
- 通過創建更集中的生態系統,提高第三方開源庫的可發現性和參與度。
相比之下,Chathages是分散式依賴管理器。沒有集中的依賴清單(就是內個CocoaPods中的SPEC倉庫),這減少了維護工作,避免了任何中心故障點。然而,開源項目的發現變得更加困難,用戶必須在github等開源網站上進行自行搜索。
CocoaPods的工程目錄中必須有一個叫做podspec的這么一個文件,其中包含有關項目的元數據並指定了工程的的編譯方式。Carthage使用了xcodebuild工具來構建依賴關系,而不是將這些依賴集成到單個工作區域中。它沒有類似podspec這樣的文件,但你的依賴項必須包括它們自己的XCODE項目,在這些項目中提供了依賴庫的編譯規則。
最終,我們創建了Carthage,因為我們想要最簡單的工具——該依賴性管理器,它在不承擔Xcode所做的工作的的情況下完成自己依賴管理的工作,並且不為框架作者創建額外的工作。雖然CocoaPods提供了許多令人驚喜的特性,但Carthage將永遠不會有,因為這樣會以增加工具的復雜度為代價。
五、CocoaPods結合Cathage進行二進制化。
不過我們可以將兩者結合起來,比如一個浩大的工程中引入了成百上千個依賴庫,如果都以源碼的形式加載的話,編譯成本難免會比較大。我們可以在CocoaPods中加載Carthage生成的framework, 來達到CocoaPods的二進制化的目的。
我們可以在CocoaPods的Podfile中添加相關的定義,具體如下所示。在else的語句塊中就是加載Carthage編譯的framework。
添加完相關Pod配置后,我們可以pod install看醫生相關的庫是否順利的加載進來了。
下方就是我們pod install后相關的內容,可以看到依賴的倉庫通過了framework的形式被引入到了我們的CocoaPods中,並且可以正常使用。
我們可以通過指定SOURCE條件來切換源碼加載。
下方是切換源碼加載后的工程文件,可以看出是與之前一致的:
今天的博客就先到這兒吧,以后有機會的話再一起看一下Carthage的源碼。