常常使用CocoaPods來管理iOS項目中的第3方庫,但是我們要使用CocoaPods來管理第3方庫,條件是要寫好Podfile文件,通過這個文件來配置第3方庫與項目之間的依賴、版本等信息。
但是,我相信很少有人完全地學習過Podfile的語法規則,包括筆者在寫本篇文章之前。今天,請大家與筆者1起來完全地學習Podfile官方教程。
之前1直想寫來著,由于包括筆者在內并沒有深入學習過它的使用。如果對之不夠了解,如何能做到善用之。因此,下面1起來探討探討吧!
官方只有1句話說明甚么是Podfile:The Podfile is a specification that describes the dependencies of the targets of one or more Xcode projects.
大概意思是:Podfile文件是1種規則描寫,用于描寫1或多個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
這里只是拋磚引玉,繼續往下看,如何1點點地掌握Podfile的語法規則。
目前根據官方文檔說明,Podfile全局配置只有1個命令:
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,官方也沒有明確說明其功能!
在我們平常開發中,我們可能永久不需要使用到此配置命令,因此大家不用太關注它!
CocoaPods就是用于管理第3方依賴的。我們通過Podfile文件配置來指定工程中的每一個target之間與第3方之間的依賴。
有以下3個命令來管理依賴:
此命令用于指定工程的依賴。我們通過Pod命令指定所依賴的第3方及第3方庫的版本范圍。
pod 'HYBMasonryAutoCellHeight'
當我們永久使用遠程倉庫中的最新版本時,我們只需要指定倉庫名便可。當有新的版本發布時,履行pod update命令,會更新至最新的版本。
由于版本之間可能會存在很大的差異,因此我們不應當采取這類方式,而是指定版本范圍或指定特定版本。
pod 'HYBLoopScrollView', '2.0'
當我們不希望版本更新,而是固定使用指定的版本時,我們應當這么寫法。當遠程有新的版本發布時,pod是不會去更新新版本的。由于版本變化可能較大,因此有時候我們希望這么做的。
pod 'HYBUnicodeReadable', '~>1.1.0'
當我們不要求固定版本號,而是指定某個范圍時,我們會像上面這么寫法。我相信大家在工程中見到最多的就是這類寫法了吧。但是,我相信很多朋友其實不知道這么寫法的意思是甚么。
它的意思是:HYBUnicodeReadable的版本可以是1.1.0到2.0.0,但是不包括2.0.0。
使用這類寫法是很有用的,因此小版本的升級1般是fix bug,當有bug被fix時,我們確切應當更新。從1.9.9升級到2.0.0時,不會去更新到2.0.0版本。我們認為從2.0.0是1個大版本,大版本的發布,通常不是fix bug,而是增加功能或改動較大。
那末有哪些符號可以指定范圍呢:
= version 要求版本大于或等于version,當有新版本時,都會更新至最新版本
pod 'AFNetworking', :path => '~/Documents/AFNetworking'
如果我們的庫是在本地的,那末我們可以通過這樣的命令來指定。由因而援用目錄,因另外部直接修改目錄中的內容,CocoaPods也會更新到最新的,所以也挺不錯的!
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號是1致的):
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文件與庫目錄是同級的,都在根目錄下!
pod 'JSONKit', :podspec => 'https://example.com/JSONKit.podspec'
如上,當我們發布到CocoaPods時,如果沒有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會被使用。
正常情況下,我們其實不需要指定,1般所開源出來的庫的podspec都是在根目錄下,所以可放心腸使用,不用斟酌太多。
例如:
// 不指定表示使用根目錄下的podspec,默許1般都會放在根目錄下 podspec // 如果podspec的名字與庫名不1樣,可以通過這樣來指定 podspec :name => 'QuickDialog' // 如果podspec不是在根目錄下,那末可以通過:path來指定路徑 podspec :path => '/Documents/PrettyKit/PrettyKit.podspec'
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)和指定依賴的范圍。1個target應當與Xcode工程的target有關聯。默許情況下,target會包括定義在塊外的依賴,除非指定不使用inherit!來繼承(說的是嵌套的塊里的繼承問題)
例子:
target 'HYBTestProject' do pod 'HYBMasonryAutoCellHeight', '~>1.1.0' end
target 'HYBTestProject' do pod 'SSZipArchive' target 'HYBTestProjectTests' do inherit! :search_paths pod 'Nimble' end end
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這是固定的寫法。
這里的配置會使用和控制工程的生成。
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.
也就是說,若不指定平臺版本,各平臺默許值以下:
默許情況下是沒有指定的,當沒有指定時,會使用Podfile目錄下與target同名的工程:
# MyGPSApp只有在FastGPS工程中才會鏈接 target 'MyGPSApp' do project 'FastGPS' ... end # MyNotesApp這個target只有在FastNotes工程中才會鏈接 target 'MyNotesApp' do project 'FastNotes' ... end
1般情況下,我們不指定project,直接使用:
target 'MyApp' do pod ... end
inhibit_all_warnings!命令是不顯示所援用的庫中的正告信息。我們可以指定全局不顯示正告信息,也能夠指定某1個庫不顯示正告信息:
pod 'SSZipArchive', :inhibit_warnings => true
通過指定use_frameworks!要求生成的是framework而不是靜態庫。
默許情況下,我們不需要指定,直接使用與Podfile所在目錄的工程名1樣就能夠了。如果要指定另外的名稱,而不是使用工程的名稱,可以這樣指定:
workspace 'MyWorkspace'
source是指定pod的來源。如果不指定source,默許是使用CocoaPods官方的source。通常我們沒有必要添加。
// 如果不想使用官方的,而是在別的地方也有,可以這樣指定 source 'https://github.com/artsy/Specs.git' // 默許是官方的source source 'https://github.com/CocoaPods/Specs.git'
Hooks可以叫它為勾子吧,與swizzling特性差不多,就是在某些操作之前,先勾起,而且讓它履行我們特定的操作。
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'
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
既然有pre_install命令,自然會想到還有1個與之對應的命令。
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.
當我們安裝完成,但是生成的工程還沒有寫入磁盤之時,我們可以指定要履行的操作。
比如,我們可以在寫入磁盤之前,修改1些工程的配置:
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命令來聲明1個pod集:
def 'CustomPods' pod 'IQKeyboardManagerSwift' end
然后,我們就能夠在需要引入的target處引入之:
target 'MyTarget' do CustomPods end
這么寫的好處是:如果有多個target,而不同target之間其實不全包括,那末可以通過這類方式來分開引入。
下面是逗視項目的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