開發 iOS 項目不可避免地要使用第三方開源庫,在使用第三方庫時,除了需要導入源碼,集成這些依賴庫還需要我們手動去配置,還有當這些第三方庫發生了更新時,還需要手動去更新項目,這就顯得非常麻煩。而 CocoaPods 的出現使得我們可以節省設置和更新第三方開源庫的時間,通過 CocoaPods,我們可... ...
CocoaPods 是什麼?
CocoaPods 是一個負責管理 iOS 項目中第三方開源庫的工具。CocoaPods 的項目源碼在 GitHub( https://github.com/CocoaPods )上管理。
開發 iOS 項目不可避免地要使用第三方開源庫,在使用第三方庫時,除了需要導入源碼,集成這些依賴庫還需要我們手動去配置,還有當這些第三方庫發生了更新時,還需要手動去更新項目,這就顯得非常麻煩。
而 CocoaPods 的出現使得我們可以節省設置和更新第三方開源庫的時間,通過 CocoaPods,我們可以將第三方的依賴庫統一管理起來,配置和更新只需要通過簡單的幾行命令即可完成。
為什麼要使用 CocoaPods?
在使用 CocoaPods 之前,開發項目需要用到第三方開源庫的時候,我們需要:
把開源庫的源代碼複製到項目中
添加一些依賴框架和動態庫
設置 -Objc,-fno-objc-arc 等參數
管理它們的更新
在使用 CocoaPods 之後,我們只需要把用到的開源庫放到一個名為 Podfile 的文件中,然後執行 pod update 就可以了,CocoaPods 就會自動將這些第三方開源庫的源碼下載下來,並且為我們的工程設置好相應的系統依賴和編譯參數。
CocoaPods 的原理
CocoaPods 的原理是將所有的依賴庫都放到另一個名為 Pods 的項目中,然後讓主項目依賴 Pods 項目,這樣就把源碼管理工作從主項目移到了 Pods 項目中。
第三方庫會被編譯成 .a 靜態庫或者 .framwork 的動態鏈接庫供我們真正的工程使用。
CocoaPods 會將所有的第三方庫以 target 的方式組成一個名為 Pods 的工程,該工程就放在剛纔新生成的 Pods 目錄下。整個第三方庫工程會生成一個名稱為 libPods.a 的靜態庫供我們的工程使用。
對於資源文件,CocoaPods 提供了一個名為 Pods-resources.sh 的 bash 腳本,該腳本在項目每次編譯的時候都會執行,將第三方庫的各種資源文件複製到目標目錄中。
原來的工程設置已經被更改了,這時候我們直接打開原來的工程文件去編譯就會報錯。我們的工程和第三方庫所在的 Pods 工程會被以一個新生成的 workspace 的形式組織和管理,方便我們直觀的管理工程和第三方庫。
CocoaPods 通過一個名為 Pods.xcconfig 的文件來在編譯時設置所有的依賴和參數。
CocoaPods 的核心組件
CocoaPods 是用 Ruby 寫的,並劃分成了若幹個 Gem 包。
與 CocoaPods 相關的兩個目錄:
~/.CocoaPods/repos/
:這個目錄存儲遠端的 podspec 文件到本地。master 是所有第三方的 podspec 索引文件。其它的是我們自定義的 podspec 索引文件。~/Library/Caches/CocoaPods/
:這個目錄就是緩存文件的存儲目錄。
CocoaPods 在解析執行過程中最重要的幾個包的路徑分別是:CocoaPods/CocoaPods、CocoaPods/Core 和 CocoaPods/Xcodeproj。
CocoaPods/CocoaPods:這是面向用戶的組件,每當執行一個 pod 命令時,這個組件將被激活。它包括了所有實用 CocoaPods 的功能,並且還能調用其它 Gem 包來執行任務。
CocoaPods/Core:Core Gem 提供了與 CocoaPods 相關的文件(主要是 Podfile 和 Podspecs)的處理。
Podfile:該文件用於配置項目所需要的第三方庫,它可以被高度定製。
Podspecs:該文件描述了一個庫將怎樣被添加進工程中。.podspec 文件可以標識該第三方庫所需要的源碼文件、依賴庫、編譯選項,以及其他第三方庫需要的配置。
CocoaPods/Xcodeproj:這個包負責處理工程文件,它能創建以及修改 .xcodeproj 文件和 .xcworkspace 文件。它也可以作為一個獨立的包使用,當你要編寫修改項目文件的腳本時,可以考慮使用 CocoaPods/Xcodeproj。
CocoaPods 的安裝
替換源
CocoaPods 是基於 ruby ecosystem 的,需要 ruby 環境,使用 ruby 的 gem 命令。所以我們的系統要有 ruby 環境。而 Mac 系統預設會安裝好 ruby 環境,可以在終端輸入 $gem sources -l
命令查看系統 ruby 預設源為 https://rubygems.org/
,但這個源在國內是訪問不到的,所以需要更換 ruby 鏡像。
我們可以使用淘寶的源 https://ruby.taobao.org/
,但是淘寶的源已經不更新維護了,所以不建議使用淘寶的源,我們最好使用 ruby-china 的源 https://gems.ruby-china.org
。
移除系統 ruby 預設源
$gem sources --remove https://rubygems.org/
使用新的源
$gem sources -a https://ruby.taobao.org/
(淘寶的源,不建議使用)或
$gem source -a https://gems.ruby-china.org
驗證是否替換成功
$gem sources -l
如果結果如下圖,表明替換成功。
安裝 CocoaPods
選擇版本
安裝最新版本
$sudo gem install -n /usr/local/bin CocoaPods
安裝指定版本$sudo gem install -n /usr/local/bin CocoaPods -v 1.0.0
安裝最新的 release beta 版本$sudo gem install -n /usr/local/bin CocoaPods --pre
安裝
$pod setup
pod setup
的作用:將所有第三方的 Podspec 索引文件更新到本地的 ~/.CocoaPods/repos 目錄下。所有的第三方開源庫的 Podspec 文件都托管在 https://github.com/CocoaPods/Specs 管理,我們需要把這個 Podspec 文件保存到本地,這樣才能使用命令pod search
來搜索一個開源庫。如果沒有執行過
pod setup
,用戶根目錄 ~ 下是找不到 .CocoaPods/repos 目錄的,沒有創建這個目錄。如果執行了
pod setup
,但是命令沒有執行成功,那麼會創建 ~/.CocoaPods/repos 目錄,只不過目錄是空的。如果執行了
pod setup
,並且命令執行成功,說明把 GitHub 上的 Podsepc 文件更新到了本地,那麼會創建 ~/.CocoaPods/repos 目錄,並且 repos 目錄里有一個 master 目錄,這個 master 目錄保存的就是 GitHub 上所有第三方開源庫的 Podspec 索引文件。
第一次執行
pod setup
時,這個 GitHub 上的 Podspec 索引文件比較大,所以第一次更新時非常慢,要耐心等待,我們可以新建一個終端視窗,輸入以下命令來查看下載文件的大小。進入文件目錄
~/.CocoaPods
$cd ~/.CocoaPods
查看文件大小
$du -sh
驗證是否安裝成功以及是否是自己需要的版本
$pod --version
安裝過程常見錯誤
Gem 版本過低
Failed to send stats: SSL_connect returned=1 errno=0 state=SSLv2/v3 read server hello A: sslv3 alert handshake failure
可以在終端輸入以下命令:
查看 Gem 的版本號
$gem -v
或者$gem --version
升級 Gem
$sudo gem update --system
如果出現以下錯誤:
ERROR: While executing gem ... (Errno::EPERM) Operation not permitted - /usr/bin/update_rubygems
則輸入以下命令來升級 Gem:
$sudo gem update -n /usr/local/bin --system
Gem 介紹:
Gem 是一個管理 Ruby 庫和程式的標準包,它通過 RubyGem(如 http://rubygems.org/ )源來查找、安裝、升級和卸載軟體包,非常的便捷。如果 Gem 的版本過低就會導致 CocoaPods 安裝失敗。
所有的 Gem 包會被安裝到
/[Ruby root]/lib/ruby/gems/[ver]/
目錄下,其中包括了 cache、doc、gems、specifications 4 個目錄,cache 下放置下載的原生 Gem 包,gems 下則放置解壓過的 Gem 包。當安裝過程中遇到問題時,可以進入這些目錄,手動刪除有問題的 Gem 包,然後重新安裝。
一些常用的 Gem 命令:
查看 Gem 配置源:
$gem sources -l
Gem 添加配置源:
$gem sources -a 源的url
Gem 刪除配置源:
$gem sources -r 源的url
更新所有 Gem 包:
$gem update
更新指定的 Gem 包:
$gem update [gemname]
(註意:此命令不會升級舊版本的包)更新 RubyGems 軟體:
$gem update --system
清除所有 Gem 包舊版本,保留最新版本:
$gem cleanup
查看 Gem 環境:
$gem environment
從 Gem 源安裝 Gem 包:
$gem install [gemname]
從本機安裝 Gem 包:
$gem install -l [gemname].gem
安裝指定版本的 Gem 包:
$gem install [gemname] --version=[版本號]
刪除指定的 Gem 包:
$gem uninstall [gemname]
(註意:此命令將刪除所有已安裝的版本)刪除某指定版本 Gem:
$gem uninstall [gemname] --version=[版本號]
查看本機已安裝的所有 Gem 包:
$gem list --local
Ruby 版本過低
ERROR: Error installing CocoaPods: activesupport requires Ruby version >= 2.2.2
在終端輸入以下命令查看當前 Ruby 版本:
$ruby -v
Ruby 是什麼?
Ruby 是一種簡單快捷的面向對象腳本語言,主要用來實現一些自動化腳本。由於 iOS 系統上沒有 Ruby 解釋器,所以它通常是在 Mac 系統上使用,在編譯前(絕非 app 運行時)進行一些自動化工作。CocoaPods 中的 podfile 其實就是一份 Ruby 代碼。
升級 Ruby
升級 Ruby 要首先安裝 RVM
RVM:Ruby Version Manager,Ruby 版本管理器,包括 Ruby 的版本管理和 Gem 庫管理(gemset)。
打開終端,執行以下命令:
$curl -L get.rvm.io | bash -s stable
期間需要輸入管理員密碼,然後會自動通過 Homebrew 安裝依賴包,等待一段時間後就可以成功安裝好 RVM。
如果出現以下錯誤:
Error running 'requirements_osx_port_libs_install curl-ca-bundle automake libtool libyaml libffi libksba', showing last 15 lines of /Users/acewill/.rvm/log/1468253599_ruby-2.3.0/ package_install_curl-ca-bundle_automake_libtool_libyaml_libffi_libksba.log https://github.com/Homebrew/homebrew/wiki/Common-Issues
原因是 Mac 上未安裝 Homebrew,需要先安裝 Homebrew。
Homebrew 是什麼?
Homebrew 是一個包管理器,用於在 Mac 上安裝一些 OS X 上沒有的 UNIX 工具。Homebrew 將這些工具統統安裝到了
/usr/local/Cellar
目錄中,併在/usr/local/bin
中創建符號鏈接。安裝 Homebrew
Homebrew 官網:http://brew.sh
從 Homebrew 官網獲取安裝命令在終端執行:
$/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
需要等待一段時間,Homebrew 安裝成功之後,重新安裝 RVM。
Homebrew 常用命令
搜索軟體:
$brew search git
安裝軟體:
$brew install git
查看軟體信息:
$brew info git
更新自己:
$brew update
檢查過時軟體:
$brew outdated
升級可以升級的軟體:
$brew upgrade
清理不需要的軟體版本及其安裝包緩存:
$brew cleanup
列出已安裝的軟體:
$brew list
卸載軟體:
$brew unstall git
RVM 安裝成功之後執行以下命令,載入 RVM 環境:
$source ~/.bashrc
$source ~/.bash_profile
$source ~/.profile
最後,執行以下命令測試是否安裝正常:
$rvm -v
通過 RVM 升級 Ruby
列出已知的 Ruby 版本
$rvm list known
安裝指定的 Ruby 版本
$rvm install 2.3.3
列出本地安裝的所有 Ruby 版本
$rvm list
指定系統預設的 Ruby 版本
$rvm use 2.3.3 --default
刪除指定的 Ruby 版本
$rvm remove 2.0.0
如果網速較慢的話,在執行
$rvm install 2.3.3
命令時,會花費很長的時間,而且很容易報時間超時的錯誤,解決辦法就是多次重試,或者等網速好的時候安裝。另一種解決辦法就是通過 Homebrew 來升級 Ruby。
打開終端,執行以下命令:
$brew install ruby
只需要等待很短的時間就可以升級 Ruby 成功。但通過這種方法升級 Ruby 之後,Gem 的版本可能不是最新的,我們只需要按照上文中提到的升級 Gem 的方法來升級 Gem 即可。但是會出現以下錯誤:
ERROR: While executing gem ... (TypeError) no implicit conversion of nil into String
解決辦法:打開 Finder-->前往-->前往文件夾,輸入路徑
/usr/local/lib/ruby/2.3.0/rubygems/installer.rb
,點擊前往,找到 installer.rb 文件,打開該文件,找到文件中的以下代碼段:if ruby_executable then question << existing
然後用以下代碼段替換找到的代碼段:
if ruby_executable then question << (existing || 'an unknown executable')
替換之後,Gem 就可以升級了。
GitHub 無法鏈接
error: RPC failed; result=56, HTTP code = 200 fatal: The remote end hung up unexpectedly fatal: early EOF fatal: index-pack failed
解決辦法:FQ,然後重新安裝。
CocoaPods 的分支不支持當前最新的 Xcode 版本
[!] An error occurred while performing
git pullon repo
master. [!] /usr/bin/git pull --ff-only
解決辦法:刪除 master 分支,重新建立新的分支,然後重新設置倉庫即可。在終端執行以下命令:
$sudo rm -fr ~/.CocoaPods/repos/master
CocoaPods 的使用
常用 CocoaPods 命令:
$pod setup
將所有第三方的 Podspec 索引文件更新到本地的
~/.CocoaPods/repos/
目錄下,更新本地倉庫。$pod repo update
執行
pod repo update
更新本地倉庫,本地倉庫完成後,即可搜索到指定的第三方庫,作用類似pod setup
。不過這個命令經常不單獨調用。比如執行pod setup
、pod search
、pod install
、pod update
會預設執行pod repo update
。$pod search 開源庫
查找某一個開源庫。
$pod list
列出所有可用的第三方庫,現在已經 2.4W+ 了,還在不斷地增長。
$pod install
根據 Podfile.lock 文件中列舉的版本號來安裝第三方框架,如果一開始 Podfile.lock 文件不存在,就會按照 Podfile 文件中列舉的版本號來安裝第三方框架。
如果檢查到當前三方庫已經有的話,那就不會去下載了。
$pod install –-no-repo-update
安裝開源庫之前,不會執行
pod repo update
指令。$pod update
將所有第三方框架更新到最新版本,並且創建一個新的 Podfile.lock 文件。
無論當前三方庫是否在項目中已經存在,都會重新下載更新。
$pod update –-no-repo-update
更新開源庫之前,不會執行
pod repo update
指令。
以下以 AFNetworking 為例介紹 CocoaPods 的使用。
在終端搜索相應的開源類庫
$pod search AFNetworking
如果 CocoaPods 支持,將會輸出搜索到的所有類庫版本和信息,以及在 Podfile 中配置的寫法,例如:
如果提示沒有找到該開源庫,但是我們這個第三方確實存在:
我們可以使用
pod setup
更新本地 podspec 索引文件,然後重新搜索。如果按照 1 的方法還是搜索不到,那我們就把
~/Library/Caches/CocoaPods/
目錄下的緩存文件刪除。然後pod setup
,再重新搜索。
進入到我們的工程目錄
$cd 我們的工程路徑
在我們的工程目錄下創建 Podfile 文件
通過 Mac 預設文本編輯器編寫
$touch podfile
創建 Podfile 文件$open podfile
打開 Podfile 文件打開 Podfile 文件之後即可編寫,編寫完成之後關閉文本編輯器即可。
使用 VIM 編輯器編寫
$vim podfile
創建 Podfile 文件並使用 VIM 編寫執行命令之後預設是編輯模式,用鍵盤輸入 i,進入輸入模式,輸入 pod 信息,完成之後按 Esc 鍵,退出輸入模式進入編輯模式,然後再輸入 : 號,進入末行模式,在 : 號後邊輸入 wq 保存退出 Podfile 文件,回到終端,繼續進行下一步。
VIM 介紹
VIM 是一個類似於 VI 的著名的功能強大、高度可定製的文本編輯器。
VI:Visual Interface,可視化介面。
VIM:VI iMproved,VI 增強版全屏編輯器,又叫模式化編輯器。
VIM 有 3 種模式:
- 編輯模式(命令模式)(預設模式)
- 輸入模式
- 末行模式
VIM 3 種模式間的轉換:
編輯 --> 輸入:
i:在當前游標所在字元的前面,轉換為輸入模式
I:在當前游標所在行的行首,轉換為輸入模式
a:在當前游標所在字元的後面,轉換為輸入模式
A:在當前游標所在行的行尾,轉換為輸入模式
o:在當前游標所在行的下方,新建一行,轉換為輸入模式
O:在當前游標所在行的上方,新建一行,轉換為輸入模式
輸入 --> 編輯:
Esc
編輯 --> 末行:
:
末行 --> 編輯:
Esc + ,或者按兩次 Esc
輸入模式和末行模式之間不能直接切換
使用 VIM 打開文件:
$vim 文件名 +#
打開文件,並定位於第 # 行$vim 文件名 +:
打開文件,並定位於最後一行
使用 VIM 關閉文件:
末行模式下關閉文件
:w --> 保存
:w! --> 強行保存
:q --> 退出
:q! --> 不保存並退出
:wq --> 保存並退出
:x --> 保存並退出編輯模式下關閉文件
ZZ --> 保存並退出
Podfile 介紹
source 'ssh://[email protected]:9830/iOS/Specs.git' source 'https://github.com/CocoaPods/Specs.git' platform :iOS, '8.0' use_frameworks! inhibit_all_warnings! workspace 'CocoaPodsTest' target 'CocoaPodsTest' do project 'CocoaPodsTest' pod 'AFNetworking' pod 'JYCarousel', '0.0.1' pod 'WCJCache', :git => "http://gitlab.9ijx.com/iOS/WCJCache.git" target :CocoaPodsTestUITests do inherit! :search_paths pod 'YYText' end end
Podfile 語法解釋:
source
指定 specs 的位置,自定義添加自己的 podspec。
- 如果沒有自定義添加 podspec,則可以不添加這一項,因為預設使用 CocoaPods 官方的 source。一旦指定了其它 source,那麼就必須指定官方的 source,如上例所示。
platform :iOS, '8.0'
指定了開源庫應該被編譯在哪個平臺以及平臺的最低版本。
如果不指定平臺版本,官方文檔里寫明各平臺預設值為 iOS:4.3,OS X:10.6,tvOS:9.0,watchOS:2.0。
use_frameworks!
使用 frameworks 動態庫替換靜態庫鏈接
Swift 項目 CocoaPods 預設 use_frameworks!
OC 項目 CocoaPods 預設 #use_frameworks!
inhibit_all_warnings!
屏蔽 CocoaPods 庫裡面的所有警告
這個特性也能在子 target 裡面定義,如果你想單獨屏蔽某 pod 裡面的警告也是可以的,例如:
pod 'JYCarousel', :inhibit_warnings => true
workspace
指定包含所有 projects 的 Xcode workspace
如果沒有指定 workspace,並且在 Podfile 所在目錄下只有一個 project,那麼 project 的名稱會被用作 workspace 的名稱
target ‘xxxx’ do ... end
指定特定 target 的依賴庫
可以嵌套子 target 的依賴庫
project
預設情況下是沒有指定的,當沒有指定時,會使用 Podfile 目錄下與 target 同名的工程
如果指定了 project,如上例所示,則 CocoaPodsTest 這個 target 只有在 CocoaPodsTest 工程中才會鏈接
inherit! :search_paths
- 明確指定繼承於父層的所有 pod,預設就是繼承的
依賴庫的基本寫法
pod 'AFNetworking' --> 不顯式指定依賴庫版本,表示每次都獲取最新版本
pod 'AFNetworking', '2.0' --> 只使用 2.0 版本
pod 'AFNetworking', '> 2.0' --> 使用高於 2.0 的版本
pod 'AFNetworking', '>= 2.0' --> 使用大於或等於 2.0 的版本
pod 'AFNetworking', '< 2.0' --> 使用小於 2.0 的版本
pod 'AFNetworking', '<= 2.0' --> 使用小於或等於 2.0 的版本
pod 'AFNetworking', '~> 0.1.2' --> 使用大於等於 0.1.2 但小於 0.2 的版本
pod 'AFNetworking', '~> 0.1' --> 使用大於等於 0.1 但小於 1.0 的版本
pod 'AFNetworking', '~> 0' --> 高於 0 的版本,寫這個限制和什麼都不寫是一個效果,都表示使用最新版本
關於 Podfile.lock:
當執行
pod install
之後,CocoaPods 會生成一個名為 Podfile.lock 的文件。Podfile.lock 應該加入到版本控制裡面,不應該把這個文件加入到 ignores 中。因為 Podfile.lock 會鎖定當前各依賴庫的版本,之後如果多次執行
pod install
不會更改版本,執行pod update
時才會更改 Podfile.lock。這樣在多人協作的時候,可以防止出現第三方庫升級時造成大家各自的第三方庫版本不一致。
在終端執行以下命令:
$pod update –-no-repo-update
成功之後打開工程,此時我們應該打開最新生成的 .xcworkspace 文件,即可使用該第三方庫。
移除項目中已經配置的類庫
打開終端,cd 到已經配置好 CocoaPods 的項目目錄下
打開該目錄下的 Podfile 文件
刪除 Podfile 文件中要移除的第三方庫
重新執行
$pod update –-no-repo-update
命令
完成以上步驟即可移除項目中已經配置的類庫
移除項目中的 CocoaPods
刪除工程文件夾下的 Podfile、Podfile.lock 和 Pods 文件夾
刪除 .xcworkspace 文件
打開 xcodeproj 文件,刪除項目中的 Pods 文件夾以及 Pods.xcconfig 引用和 libpods.a 靜態庫
打開 Build Phases 選項,刪除
Check Pods Manifest.lock
、Copy Pods Resources
和Embeded Pods Frameworks
選項
完成以上步驟即可移除項目中的 CocoaPods,項目即可編譯運行。
CocoaPods 的卸載
在終端執行以下命令:
$sudo gem uninstall CocoaPods
需要輸入密碼,之後等待很短時間就會顯示卸載成功。
卸載指定版本的 CocoaPods:
$sudo gem uninstall CocoaPods -v 0.39.0