前言
假設(shè)你已經(jīng)非常熟練的使用cocoapods來(lái)管理私有庫(kù),并且實(shí)現(xiàn)了組件化的APP設(shè)計(jì)架構(gòu)晾剖。這篇文章將會(huì)幫助你將私有庫(kù)編譯成二進(jìn)制文件,這樣做的好處是會(huì)大大縮短編譯工程的時(shí)間沽损,提升工作的效(bi)率(ge).
目標(biāo)
我們當(dāng)前最重要的目標(biāo)是將私有庫(kù)編譯成二進(jìn)制文件,但是也有諸多限制條件:
- 盡量做到不修改原來(lái)私有庫(kù)的所有版本的任何代碼
- 在任何時(shí)候都可以隨意切換源碼和二進(jìn)制文件,以方便調(diào)試
- 所依賴的第三方庫(kù)不參與二進(jìn)制編譯
步驟
新建私有Cocoapods庫(kù)
這里我將新建一個(gè)示例的私有庫(kù)工程,對(duì)制作私有Cocoapods庫(kù)不是非常了解的,可以去先看看其他文章.
$ pod lib create CCDemoLib
按照提示信息依次填寫(xiě)選項(xiàng),完成之后Xcode會(huì)被自動(dòng)打開(kāi)到CCDemoLib
的pod工程.刪除pod目錄下的ReplaceMe.m
文件.
這里,我將建立兩個(gè)子庫(kù).一個(gè)CCUI
和CCNetwork
,一個(gè)CCDemo.h
的頭文件.該頭文件用來(lái)導(dǎo)入所有子庫(kù)的頭文件.CCDemoLib.podspec
文件如下:
Pod::Spec.new do |s|
s.name = 'CCDemoLib'
s.version = '0.1.0'
s.summary = '一個(gè)測(cè)試二進(jìn)制化的私有庫(kù)'
s.description = '一個(gè)測(cè)試二進(jìn)制化的私有庫(kù)'
s.homepage = 'https://github.com/zhahao/CCDemoLib'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'zhahao' => '506902638@qq.com' }
s.source = { :git => 'https://git.coding.net/zhahao/CCDemoLib.git', :tag => s.version.to_s }
s.ios.deployment_target = '8.0'
s.source_files = 'CCDemoLib/Classes/CCDemo.h'
s.subspec 'CCNetwork' do |ss|
ss.source_files = 'CCDemoLib/Classes/CCNetwork/**/*'
ss.dependency 'AFNetworking', '~> 2.3'
end
s.subspec 'CCUI' do |ss|
ss.source_files = 'CCDemoLib/Classes/CCUI/**/*'
ss.dependency 'SDWebImage', '~> 4.1.0'
end
end
執(zhí)行pod install
,安裝完成之后的目錄結(jié)構(gòu)是這樣的:
我們將工程推到遠(yuǎn)程Git倉(cāng)庫(kù)
? CCDemoLib git:(master) ? git add origin https://git.coding.net/zhahao/CCDemoLib.git
? CCDemoLib git:(master) ? git add .
? CCDemoLib git:(master) ? git commit -m 'init project'
? CCDemoLib git:(master) git push origin master
發(fā)布到私有索引庫(kù)
添加完tag,推到索引庫(kù),這里其實(shí)不需要驗(yàn)證的,如果有錯(cuò)誤,自然也就推送不進(jìn)去.等幾分鐘...
? CCDemoLib git:(master) git tag 0.1.0
? CCDemoLib git:(master) git push --tags
? CCDemoLib git:(master) pod repo push CCPodSpec CCDemoLib.podspec --allow-warnings
然后,成功了~ 到此,我們就發(fā)布了一個(gè)正常的私有庫(kù).
二進(jìn)制化
前面簡(jiǎn)單介紹了下私有庫(kù)的創(chuàng)建,接下來(lái)介紹私有庫(kù)的二進(jìn)制化方案.
iOS里面的靜態(tài)庫(kù)分為.framework和.a兩種類型,它們的區(qū)別是.framework會(huì)包含資源文件,而.a文件是不包含資源文件.一般情況下我們都需要.a類型的靜態(tài)庫(kù),這樣每個(gè)組件的資源都不會(huì)安裝到主工程里面去,避免了資源的重復(fù)問(wèn)題,但是主工程里面需要導(dǎo)入需要的所有的圖片等資源.
下面以.framework為例子:
生成framework
直接上圖:
修改podfile文件
執(zhí)行 'pod install',等安裝完成之后,編譯剛才的CCDemoBinary
target,找到CCDemoBinary.framework,位置如下:
右鍵show in finder 找到CCDemoBinary.framework
文件,選Release-iphoneos
文件夾里面的那個(gè).
至此,framework已經(jīng)搞定了,接下來(lái)我們要去修改CCDemoLib.podspec
文件
修改CCDemoLib.podspec
之前說(shuō)過(guò),我們需要隨時(shí)切換源碼和二進(jìn)制文件,所以我們可以利用環(huán)境變量來(lái)處理這兩種情況
$ CCDemoLib_Source=1 pod install
CCDemoLib_Source
就是設(shè)置了一個(gè)環(huán)境變量,在.podspec
文件中,可以使用ENV['CCDemoLib_Source']
來(lái)獲取
修改之后的CCDemoLib.podspec
文件
Pod::Spec.new do |s|
s.name = 'CCDemoLib'
s.version = '0.1.0'
s.summary = '一個(gè)測(cè)試二進(jìn)制化的私有庫(kù)'
s.description = '一個(gè)測(cè)試二進(jìn)制化的私有庫(kù)'
s.homepage = 'https://github.com/zhahao/CCDemoLib'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'zhahao' => '506902638@qq.com' }
s.source = { :git => 'https://git.coding.net/zhahao/CCDemoLib.git', :tag => s.version.to_s }
s.ios.deployment_target = '8.0'
if ENV['CCDemoLib_Source'] || ENV['AllLib_Source']
s.source_files = 'CCDemoLib/Classes/CCDemo.h'
s.subspec 'CCNetwork' do |ss|
ss.source_files = 'CCDemoLib/Classes/CCNetwork/**/*'
ss.dependency 'AFNetworking', '~> 2.3'
end
s.subspec 'CCUI' do |ss|
ss.source_files = 'CCDemoLib/Classes/CCUI/**/*'
ss.dependency 'SDWebImage', '~> 4.1.0'
end
else
s.source_files = 'CCDemoLib/Classes/**/*.h'
s.vendored_frameworks = 'CCDemoLib/Products/CCDemoBinary.framework'
s.dependency 'AFNetworking', '~> 2.3'
s.dependency 'SDWebImage', '~> 4.1.0'
end
end
中間的if...else...end
的邏輯中AllLib_Source
環(huán)境變量的意思是所有私有庫(kù)判斷,CCDemoLib_Source
是當(dāng)前的私有庫(kù)判斷.
當(dāng)設(shè)置環(huán)境變量為true,那么,我們這個(gè)pod庫(kù)的source_files
和dependency
都是引用源碼.否則,我們就將source_files
全部設(shè)置為頭文件.并且設(shè)置vendored_frameworks
為剛才拖進(jìn)來(lái)的framework,第三方庫(kù)全部為依賴關(guān)系,也就是全部為源碼.
- 當(dāng)我想讓所有私有庫(kù)顯示源碼,只需要設(shè)置
AllLib_Source=1
- 當(dāng)我們指定某一個(gè)私有庫(kù)為源碼,其他都為二進(jìn)制,只需要設(shè)置
CCDemoLib_Source=1
- 當(dāng)我們想讓所有私有庫(kù)都是二進(jìn)制,那么就什么環(huán)境變量都不設(shè)置
測(cè)試工程的framework私有庫(kù)的結(jié)構(gòu)目錄如下:
可以看到,所有的.m文件全部沒(méi)有了.
自此,我們就完成了大部分工作.最后就是要將修改后的所有文件提交到Git遠(yuǎn)程倉(cāng)庫(kù)和pod索引庫(kù).
提交修改,更新索引庫(kù)
git提交修改:
? CCDemoLib git:(master) ? git add .
? CCDemoLib git:(master) ? git commit -m '二進(jìn)制化該私有庫(kù)'
? CCDemoLib git:(master) git push origin master
刪除之前的tag
? CCDemoLib git:(master) git tag
0.1.0
? CCDemoLib git:(master) git tag -d 0.1.0
? CCDemoLib git:(master) git push origin :0.1.0
設(shè)置新的同名tag并提交
? CCDemoLib git:(master) git tag 0.1.0
? CCDemoLib git:(master) git push --tags
提交新的索引庫(kù)
? CCDemoLib git:(master) pod repo push CCPodSpec CCDemoLib.podspec --allow-warnings
等幾分鐘成功之后,可以查看一下索引庫(kù)是否更新了該版本的.podspec
文件.
到此為止,我們所有的操作都沒(méi)有修改源碼,也實(shí)現(xiàn)了我們之前的三個(gè)限制.
清除緩存
由于pod update
的原理是先從緩存中讀取,即Podfile.lock
文件,由于我們沒(méi)有修改私有庫(kù)的版本號(hào),所以我們需要先清空緩存,讓索引庫(kù)重新從遠(yuǎn)程拉取.podspec
文件. 所以,當(dāng)你每次二進(jìn)制化一個(gè)私有庫(kù)成功之后,都需要清空緩存,不然執(zhí)行pod install
之后都是源碼,而不是二進(jìn)制文件.
? CCDemoLib git:(master) pod cache clean --all
使用
在你的APP主工程里面,執(zhí)行pod install
或者pod update
:
-
$ CCDemoLib_Source=1 pod update
只安裝了CCDemoLib
私有庫(kù)為源碼 -
$ pod update
安裝了所有私有庫(kù)為二進(jìn)制 -
$ AllLib_Source=1 pod update
安裝了所有私有庫(kù)為源碼
我們新建了一個(gè)測(cè)試主工程CocoapodsBinary
platform :ios, '8.0'
use_frameworks!
source 'https://git.coding.net/zhahao/CCPodSpec.git'
source 'https://github.com/CocoaPods/Specs.git'
target 'CocoapodsBinary' do
pod 'CCDemoLib'
end
執(zhí)行pod install,完成之后pod目錄結(jié)構(gòu)上如下:
自此,我們就徹底完成了私有庫(kù)的二進(jìn)制!
核心
私有庫(kù)的二進(jìn)制化核心就是將原來(lái)的私有庫(kù)編譯出一個(gè)framework,然后修改.podspec
文件,根據(jù)不同的環(huán)境變量獲取不同的對(duì)私有庫(kù)的描述信息,這樣通過(guò)pod
進(jìn)行安裝和更新的時(shí)候,安裝了不同的文件暂筝。
下一期,我將使用fastlane來(lái)簡(jiǎn)化一些流程,避免做一些重復(fù)的操作和可能帶來(lái)的操作失誤.