Podfile文件管理

經常使用CocoaPods來管理iOS項目中的第三方庫,但是我們要使用CocoaPods來管理第三方庫,前提是要寫好Podfile文件,通過這個文件來配置第三方庫與項目之間的依賴、版本等信息。

但是,我相信很少有人完整地學習過Podfile的語法規則,包括筆者在寫本篇文章之前。今天,請大家與筆者一起來完整地學習Podfile官方教程。

之前一直想寫來著,因為包括筆者在內并沒有深入學習過它的使用。如果對之不夠了解,如何能做到善用之。因此,下面一起來探討探討吧!

什么是Podfile

官方只有一句話說明什么是Podfile:The Podfile is a specification that describes the dependencies of the targets of one or more Xcode projects.

大概意思是:Podfile文件是一種規則描述,用于描述一或多個Xcode工程的targets之間的依賴。

Podfile可以很簡單:

target 'MyApp' pod 'AFNetworking', '~> 1.0'

也可以很復雜:

platform :ios, '9.0' inhibit_all_warnings! target 'MyApp' do ?pod 'ObjectiveSugar', '~> 0.5' ?target 'MyAppTests' do ? ?inherit! :search_paths ? ?pod 'OCMock', '~> 2.0.1' ?end end post_install do |installer| ?installer.pods_project.pod_targets.each do |target| ? ?puts '#{target.name}' ?end end

這里只是拋磚引玉,繼續往下看,如何一點點地掌握Podfile的語法規則。

Podfile全局配置

目前根據官方文檔說明,Podfile全局配置只有一個命令:

install!

官方說明它的作用是:Specifies the installation method to be used when CocoaPods installs this Podfile.(大概意思是:指定CocoaPods安裝Podfile時所使用的安裝方法)

例如:

install! 'cocoapods', ? ? ? ? :deterministic_uuids => false, ? ? ? ? :integrate_targets => false

目前支持的key有:

:clean :deduplicate_targets :deterministic_uuids :integrate_targets :lock_pod_sources

這個沒有見過任何工程里邊有人使用過,相信99%的人兒都是使用默認的全局配置。對于這幾個key,官方也沒有明確說明其功能!

在我們日常開發中,我們可能永遠不需要使用到此配置命令,因此大家不用太關注它!

Dependencies(依賴)

CocoaPods就是用于管理第三方依賴的。我們通過Podfile文件配置來指定工程中的每個target之間與第三方之間的依賴。

有以下三個命令來管理依賴:

pod 指定特定依賴。比如指定依賴AFNetwroking

podspec 提供簡單的API來創建podspec

target 在我們的工程中,通過target指定所依賴的范圍。

Pod命令

此命令用于指定工程的依賴。我們通過Pod命令指定所依賴的第三方及第三方庫的版本范圍。

永遠使用最新版本

pod 'HYBMasonryAutoCellHeight'

當我們永遠使用遠程倉庫中的最新版本時,我們只需要指定倉庫名即可。當有新的版本發布時,執行pod update命令,會更新至最新的版本。

因為版本之間可能會存在很大的差異,因此我們不應該采用這種方式,而是指定版本范圍或者指定特定版本。

使用固定版本

pod 'HYBLoopScrollView', '2.0'

當我們不希望版本更新,而是固定使用指定的版本時,我們應該這么寫法。當遠程有新的版本發布時,pod是不會去更新新版本的。由于版本變化可能較大,因此有時候我們希望這么做的。

指定版本范圍

pod 'HYBUnicodeReadable', '~>1.1.0'

當我們不要求固定版本號,而是指定某個范圍時,我們會像上面這么寫法。我相信大家在工程中見到最多的就是這種寫法了吧。但是,我相信很多朋友并不知道這么寫法的意思是什么。

它的意思是:HYBUnicodeReadable的版本可以是1.1.0到2.0.0,但是不包括2.0.0。

使用這種寫法是很有用的,因此小版本的升級一般是fix bug,當有bug被fix時,我們確實應該更新。從1.9.9升級到2.0.0時,不會去更新到2.0.0版本。我們認為從2.0.0是一個大版本,大版本的發布,通常不是fix bug,而是增加功能或者改動較大。

那么有哪些符號可以指定范圍呢:

= version 要求版本大于或者等于version,當有新版本時,都會更新至最新版本

< version 要求版本小于version,當超過version版本后,都不會再更新

<= version 要求版本小于或者等于version,當超過version版本后,都不會再更新

~> version 比如上面說明的version=1.1.0時,范圍在[1.1.0, 2.0.0)。注意2.0.0是開區間,也就是不包括2.0.0。

使用本地庫

pod 'AFNetworking', :path => '~/Documents/AFNetworking'

如果我們的庫是在本地的,那么我們可以通過這樣的命令來指定。由于是引用目錄,因此外部直接修改目錄中的內容,CocoaPods也會更新到最新的,所以也挺不錯的!

通過倉庫的podspec引入

Sometimes you may want to use the bleeding edge version of a Pod. Or a specific revision. If this is the case, you can specify that with your pod declaration.

當我們需要使用庫的混合邊緣版本,或者指定的修訂版本,我們可以通過指定像下面這樣的聲明。

使用倉庫的master(主干):

pod 'AFNetworking', :git => 'https://github.com/gowalla/AFNetworking.git'

不是使用master,而是使用指定的分支:

pod 'AFNetworking', :git => 'https://github.com/gowalla/AFNetworking.git', :branch => 'dev'

使用指定的tag(標簽,發布庫的版本時,通常版本號與tag號是一致的):

pod 'AFNetworking', :git => 'https://github.com/gowalla/AFNetworking.git', :tag => '0.7.0'

使用指定的提交版本:

pod 'AFNetworking', :git => 'https://github.com/gowalla/AFNetworking.git', :commit => '082f8319af'

官方明確說明要求podspec在根目錄下:

The podspec file is expected to be in the root of the repository, if this library does not have a podspec file in its repository yet, you will have to use one of the approaches outlined in the sections below.

也就是說與工程同級!比如AFNetworking中的podspec文件與庫目錄是同級的,都在根目錄下!

從外部podspec引入

pod 'JSONKit', :podspec => 'https://example.com/JSONKit.podspec'

如上,當我們發布到CocoaPods時,如果沒有podspec不是在根目錄下,而是在外部,可以通過’:podspec’命令來指定外部鏈接。

podspec

Use just the dependencies of a Pod defined in the given podspec file. If no arguments are passed the first podspec in the root of the Podfile is used. It is intended to be used by the project of a library. Note: this does not include the sources derived from the podspec just the CocoaPods infrastructure.

大概意思是:使用給定的podspec所指定的pod依賴。如果沒有指定參數,根目錄下的podspec會被使用。

正常情況下,我們并不需要指定,一般所開源出來的庫的podspec都是在根目錄下,所以可放心地使用,不用考慮太多。

例如:

// 不指定表示使用根目錄下的podspec,默認一般都會放在根目錄下 podspec // 如果podspec的名字與庫名不一樣,可以通過這樣來指定 podspec :name => 'QuickDialog' // 如果podspec不是在根目錄下,那么可以通過:path來指定路徑 podspec :path => '/Documents/PrettyKit/PrettyKit.podspec'

target

Defines a CocoaPods target and scopes dependencies defined within the given block. A target should correspond to an Xcode target. By default the target includes the dependencies defined outside of the block, unless instructed not to inherit! them.

大概意思是:在給定的塊內定義pod的target(Xcode工程中的target)和指定依賴的范圍。一個target應該與Xcode工程的target有關聯。默認情況下,target會包含定義在塊外的依賴,除非指定不使用inherit!來繼承(說的是嵌套的塊里的繼承問題)

例子:

我們指定HYBTestProject這個target可以訪問HYBMasonryAutoCellHeight庫:

target 'HYBTestProject' do ?pod 'HYBMasonryAutoCellHeight', '~>1.1.0' end

指定HYBTestProject這個target可以訪問SSZipArchive,但是它不能訪問Nimble;但是,HYBTestProjectTests這個target可以訪問Nimble,默認是繼承塊外的,而且這里指定了inherit!繼承,因此它也能訪問SSZipArchive:

target 'HYBTestProject' do ?pod 'SSZipArchive' ?target 'HYBTestProjectTests' do ? ?inherit! :search_paths ? ?pod 'Nimble' ?end end

target塊內可以有多個target子塊:

target 'ShowsApp' do ?pod 'ShowsKit' ?# 可以訪問ShowsKit ShowTVAuth,其中ShowsKit是繼承于父層的 ?target 'ShowsTV' do ? ?pod 'ShowTVAuth' ?end ?# 可以訪問Specta Expecta ?# 同時也可以訪問ShowsKit,它是明確指定繼承于父層的所有pod ?target 'ShowsTests' do ? ?inherit! :search_paths ? ?pod 'Specta' ? ?pod 'Expecta' ?end end

注意:Inheriting only search paths。也就是說inherit! :search_paths這是固定的寫法。

Target configuration

這里的配置會使用和控制工程的生成。

platform

platform :ios, '7.0' platform :ios

如果沒有指定版本,官方默認值說明如下:

CocoaPods provides a default deployment target if one is not specified. The current default values are 4.3 for iOS, 10.6 for OS X, 9.0 for tvOS and 2.0 for watchOS.

也就是說,若不指定平臺版本,各平臺默認值如下:

iOS:4.3

OS X:10.6

tvOS:9.0

watchOS:2.0

project

默認情況下是沒有指定的,當沒有指定時,會使用Podfile目錄下與target同名的工程:

# MyGPSApp只有在FastGPS工程中才會鏈接 target 'MyGPSApp' do ?project 'FastGPS' ?... end # MyNotesApp這個target只有在FastNotes工程中才會鏈接 target 'MyNotesApp' do ?project 'FastNotes' ?... end

一般情況下,我們不指定project,直接使用:

target 'MyApp' do ? pod ... end

inhibit_all_warnings!

inhibit_all_warnings!命令是不顯示所引用的庫中的警告信息。我們可以指定全局不顯示警告信息,也可以指定某一個庫不顯示警告信息:

pod 'SSZipArchive', :inhibit_warnings => true

use_frameworks!

通過指定use_frameworks!要求生成的是framework而不是靜態庫。

workspace

默認情況下,我們不需要指定,直接使用與Podfile所在目錄的工程名一樣就可以了。如果要指定另外的名稱,而不是使用工程的名稱,可以這樣指定:

workspace 'MyWorkspace'

source

source是指定pod的來源。如果不指定source,默認是使用CocoaPods官方的source。通常我們沒有必要添加。

// 如果不想使用官方的,而是在別的地方也有,可以這樣指定 source 'https://github.com/artsy/Specs.git' // 默認是官方的source source 'https://github.com/CocoaPods/Specs.git'

Hooks

Hooks可以叫它為勾子吧,與swizzling特性差不多,就是在某些操作之前,先勾起,而且讓它執行我們特定的操作。

plugin

Specifies the plugins that should be used during installation.

Use this method to specify a plugin that should be used during installation, along with the options that should be passed to the plugin when it is invoked.

例如,指定在安裝期間使用cocoapods-keys和slather這兩個插件:

plugin 'cocoapods-keys', :keyring => 'Eidolon' plugin 'slather'

pre_install

This hook allows you to make any changes to the Pods after they have been downloaded but before they are installed.

當我們下載完成,但是還沒有安裝之時,會勾起來,然后可以通過pre_install指定要做的事,做完后才進入安裝階段。

比如:在下載完成但未安裝之前,我們就可以指定在干些什么:

pre_install do |installer| ?# Do something fancy! end

post_install

既然有pre_install命令,自然會想到還有一個與之對應的命令。

This hook allows you to make any last changes to the generated Xcode project before it is written to disk, or any other tasks you might want to perform.

當我們安裝完成,但是生成的工程還沒有寫入磁盤之時,我們可以指定要執行的操作。

比如,我們可以在寫入磁盤之前,修改一些工程的配置:

post_install do |installer| ?installer.pods_project.targets.each do |target| ? ?target.build_configurations.each do |config| ? ? ?config.build_settings['GCC_ENABLE_OBJC_GC'] = 'supported' ? ?end ?end end

def

我們還可以通過def命令來聲明一個pod集:

def 'CustomPods' ? pod 'IQKeyboardManagerSwift' end

然后,我們就可以在需要引入的target處引入之:

target 'MyTarget' do ? CustomPods end

這么寫的好處是:如果有多個target,而不同target之間并不全包含,那么可以通過這種方式來分開引入。

逗視項目的Podfile

下面是逗視項目的Podfile,這是經過筆者整理的:

platform :ios, '8.0' use_frameworks! inhibit_all_warnings! def shared_pods ?pod 'Alamofire', '~> 3.0' ?pod 'Kingfisher', '~> 1.6' ?pod 'MJRefresh' ?pod 'SDCycleScrollView','~> 1.3' ?pod 'APParallaxHeader' ?pod 'RoundImageView', '~> 1.0.1' ?pod 'StrechyParallaxScrollView', '~> 0.1' ?pod 'TextFieldEffects' ?pod 'IQKeyboardManagerSwift' ?pod 'SwiftyJSON' ?pod 'Validator' ?pod 'Qiniu', '~> 7.0' ?pod 'Google-Mobile-Ads-SDK', '~> 7.0' end target 'ds_ios' ?do ?shared_pods end

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,663評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,125評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,506評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,614評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,402評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,934評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,021評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,168評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,690評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,596評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,784評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,288評論 5 357
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,027評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,404評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,662評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,398評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,743評論 2 370

推薦閱讀更多精彩內容