CocoaPods 開源庫的制作過程:
- 添加私有Pod倉庫迷帜,用來存儲(chǔ)私有Pod庫的podspec文件物舒,類似CocoaPods的官方repo庫(~/.cocoapods/repos)
- 創(chuàng)建私有Pod庫的podspec文件(分全新創(chuàng)建和已存在工程兩種情況)
- 編輯podspec文件
- 測(cè)試podspec文件是否可用
- 本地測(cè)試podspec文件
- 向私有Pod庫提交podspec文件
- 添加到CocoaPods 官方庫
- Pod庫的更新維護(hù)
1. 添加私有Pod倉庫
在 GitHub 創(chuàng)建一個(gè) MySpecs 的空倉庫色洞,將遠(yuǎn)端的私有Specs倉庫clone到本地.cocoapods目錄下:
$ pod repo add MySpecs https://github.com/Wanlima/MySpecs.git
刪除私有Pod倉庫:
$ pod repo remove MySpecs
2. 創(chuàng)建podspec文件
一、 通過模板創(chuàng)建Pod項(xiàng)目工程文件冠胯,會(huì)包含一個(gè)podspec文件火诸,不需要單獨(dú)創(chuàng)建:(如果已有組件項(xiàng)目且在Git的版本管理下,可以直接進(jìn)行入第二步)
$ pod lib create podTestLibrary
$ git add .
$ git commit -s -m "Initial Commit of Library"
#添加遠(yuǎn)端倉庫
$ git remote add origin https://github.com/Wanlima/PodTestLibary.git
$ git push origin master
二荠察、不是通過模板創(chuàng)建的Pod項(xiàng)目工程文件置蜀,cd到工程文件目錄下 ,在終端執(zhí)行命令:(如果通過模板命令生成悉盆,已經(jīng)存在podspec文件盯荤,跳過這一步)
$ pod spec create PodTestLibary https://github.com/Wanlima/PodTestLibary.git
PodTestLibary是podspec文件名,如果要實(shí)現(xiàn)這一步焕盟,你需要先將你的工程push到遠(yuǎn)端秋秤。
3. 編輯podspec文件
用VSCode打開這個(gè)文件,安裝Ruby和CocoaPods語法的插件,或者使用其他的文本編輯器打開灼卢,把編輯器的格式改成Ruby就能看到語法高亮绍哎,編輯podspec里面的信息(附:官方文檔):
s.name = "xxxx" #庫的名字
s.version = "0.0.1" #版本號(hào),當(dāng)私有庫需要更新的時(shí)候只要修改這個(gè)值鞋真,自行維護(hù)
s.summay = "xxxxxx" #庫的簡(jiǎn)介崇堰,pod search 顯示在上面的介紹
s.description = "xxxxxxxx" #庫的詳細(xì)描述
s.homepage = "https://xxxx" #主頁地址,pod search 會(huì)顯示涩咖,一般填寫倉庫的地址就行了
s.license = "MIT" #開源協(xié)議海诲,項(xiàng)目文件目錄下需要有一個(gè)MIT開源協(xié)議文件
s.author = { "name" => "xxxxxx@qq.com" } #作者名字、郵箱
s.platform = :ios, "7.0" #庫最低支持的系統(tǒng)版本
s.source = { :git => "https://github.com/CharlsPrince/CommonExtension.git", :tag => "#{s.version}" } #資源地址抠藕,pod install 的時(shí)候會(huì)根據(jù)這個(gè)地址去下載你的想要庫饿肺,以及下載的版本,必須要跟s.version一致盾似。
s.source_files = "xxxx" #這個(gè)很重要敬辣,指定資源文件,前綴就是.podspec文件當(dāng)前路徑零院,只用寫之后的路徑溉跃,如Class/*是指Class文件夾下的所有文件,但不包括子文件夾里面的文件告抄、Class/**/*是指包含所有Class文件夾下的文件撰茎,包括子文件、Class/**/*.{h,m}是指包含所有Class文件夾下的后綴為.h或.m的文件打洼,當(dāng)然也可以指定文件龄糊。
s.requires_arc = true #是否支持arc
>>>>>以下是可選描述<<<<<
#s.resource = "icon.png" #資源文件,包括圖片和xib文件
# s.dependency "JSONKit", "~> 1.4" #需要依賴的三方庫
#s.framework = "SomeFramework" #需要依賴的框架
#s.public_header_files = '' #公開的頭文件募疮,如果不沒公開炫惩,用戶在用的時(shí)候可能引不到響應(yīng)的頭文件
s.subspec 'subFolder' do |ss|
ss.source_files = 'Class/xxx/**/*.{h,m}'
ss.public_header_files = "Class/xxx/**/*.{h}"
end #這個(gè)是子依賴庫银酬,因?yàn)槿绻覀冎皇怯胹.source_files來指定文件才避,那么用戶在pod下來之后所有的文件都在同一個(gè)目錄下树肃,沒有子文件夾响禽,如果想要分下類毛嫉,用s.subspec航瞭,每一個(gè)subspec可以分一個(gè)子文件夾薪介,但是記得一定要將.h文件通過ss.public_header_files公開澜搅,不然有可能會(huì)找不到頭文件退敦。
4. 測(cè)試podspec文件是否可用:
編輯完podspec文件后粘咖,可在終端執(zhí)行以下命令,檢查文件是否可用:
$ pod lib lint
或
$ pod spec lint
注意項(xiàng)
- pod lib lint 所編譯的源代碼是來自于podspec所在目錄而不是source所指定git地址
- pod spec lint 會(huì)聯(lián)網(wǎng)校驗(yàn)侈百,通過source中的git地址獲取源代碼瓮下,同時(shí)還會(huì)校驗(yàn)git地址上是否有對(duì)應(yīng)version字段的tag
- 執(zhí)行完忠聚,如果有錯(cuò)就根據(jù)錯(cuò)誤修改podspec文件,通過則繼續(xù)
- 基本通過的話你就直接可以使用這個(gè)庫了,可以創(chuàng)建一個(gè)工程試驗(yàn)一下唱捣,在這個(gè)新建個(gè)工程里面新建一個(gè)Podfile文件并輸入
當(dāng)你看到
-> PodTestLibrary (0.1.0)
PodTestLibrary passed validation.
時(shí)两蟀,說明驗(yàn)證通過了,不過這只是這個(gè)podspec文件是合格的震缭,不一定說明這個(gè)Pod是可以用的赂毯,我們需要在本地做一下驗(yàn)證。
5. 本地測(cè)試podspec文件
我們可以創(chuàng)建一個(gè)新的項(xiàng)目拣宰,在這個(gè)項(xiàng)目的Podfile文件中直接指定剛才創(chuàng)建編輯好的podspec文件党涕,看是否可用。 在Podfile中我們可以這樣編輯巡社,有兩種方式
platform :ios, '7.0'
pod 'PodTestLibrary', :path => '~/code/Cocoapods/podTest/PodTestLibrary' # 指定路徑
pod 'PodTestLibrary', :podspec => '~/code/Cocoapods/podTest/PodTestLibrary/PodTestLibrary.podspec' # 指定podspec文件
然后執(zhí)行pod install命令安裝依賴膛堤,打開項(xiàng)目工程,可以看到庫文件都被加載到Pods子項(xiàng)目中了晌该,不過它們并沒有在Pods目錄下肥荔,而是跟測(cè)試項(xiàng)目一樣存在于Development Pods/PodTestLibrary中,這是因?yàn)槲覀兪窃诒镜販y(cè)試朝群,而沒有把podspec文件添加到Spec Repo中的緣故燕耿。
6. 向私有Pod庫提交podspec文件:
因?yàn)閜odspec文件中獲取Git版本控制的項(xiàng)目還需要tag號(hào),所以我們要打上一個(gè)tag:
$ git tag -m "first release" 0.1.0
$ git push --tags #推送tag到遠(yuǎn)端倉庫
然后
$ pod repo push MySpecs PodTestLibrary.podspec
如果提交成功姜胖,去 ~/.cocoapods/repos/MySpecs 文件夾下就能找到你創(chuàng)建的私有庫了誉帅,當(dāng)然,只是podspec文件哦右莱,因?yàn)?~/.cocoapods/repos/ 只是用來保存podspec文件.再去看我們的MySpecs遠(yuǎn)端倉庫蚜锨,也有了一次提交,這個(gè)podspec也已經(jīng)被Push上去了慢蜓。
至此亚再,我們的這個(gè)組件庫就已經(jīng)制作添加完成了,使用pod search命令就可以查到我們自己的庫了胀瞪,相信怎么使用就不需要我在這里詳細(xì)說明了针余。
7. 添加到Cocoapods的官方庫
注冊(cè)spec
并推送到遠(yuǎn)程倉庫
使用trunk
進(jìn)行注冊(cè)
#填寫驗(yàn)證郵箱饲鄙,稍后通過郵件驗(yàn)證
pod trunk register xxx@xxx.com 'Name' --verbose
在終端會(huì)打印以下信息
opening connection to trunk.cocoapods.org:443...
opened
starting SSL for trunk.cocoapods.org:443...
SSL established
<- "POST /api/v1/sessions HTTP/1.1\r\nContent-Type: application/json; charset=utf-8\r\nAccept: application/json; charset=utf-8\r\nUser-Agent: CocoaPods/1.6.0.rc.1\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nHost: trunk.cocoapods.org\r\nContent-Length: 70\r\n\r\n"
<- "{\"email\":\"wangwanli_code@163.com\",\"name\":\"Passion\",\"description\":null}"
-> "HTTP/1.1 201 Created\r\n"
-> "Date: Thu, 21 Mar 2019 01:13:18 GMT\r\n"
-> "Connection: keep-alive\r\n"
-> "Strict-Transport-Security: max-age=31536000\r\n"
-> "Content-Type: application/json\r\n"
-> "Content-Length: 195\r\n"
-> "X-Content-Type-Options: nosniff\r\n"
-> "Server: thin 1.6.2 codename Doc Brown\r\n"
-> "Via: 1.1 vegur\r\n"
-> "\r\n"
reading 195 bytes...
-> "{\"created_at\":\"2019-03-21 01:13:18 UTC\",\"valid_until\":\"2019-07-27 01:13:18 UTC\",\"verified\":false,\"created_from_ip\":\"180.168.223.146\",\"description\":null,\"token\":\"5ef408511f16a93db35c2ae18e333d4b\"}"
read 195 bytes
Conn keep-alive
[!] Please verify the session by clicking the link in the verification email that has been sent to wangwanli_code@163.com
登錄注冊(cè)郵箱會(huì)收到一封認(rèn)證郵件凄诞,點(diǎn)擊鏈接完成認(rèn)證,驗(yàn)證成功之后忍级,使用終端命令進(jìn)行推送
# pod trunk push 完整的.podspec文件名
pod trunk push PodTestLibary.podspec --allow-warnings
到這里CocoaPods依賴庫就發(fā)布成功了帆谍。
這里說的是添加到私有的
Repo
,由于是示例就沒有發(fā)布到Cocoapods
的官方庫了轴咱,具體可以查看官方文檔汛蝙。
8. 更新維護(hù)podspec
我已經(jīng)制作好了PodTestLibrary的0.1.0版本烈涮,現(xiàn)在我對(duì)他進(jìn)行升級(jí)工作,這次我添加了更多的模塊到PodTestLibrary之中窖剑,包括工具類坚洽,底層Model及UIKit擴(kuò)展等,這里又嘗試了一下subspec功能西土,給PodTestLibrary創(chuàng)建了多個(gè)子分支讶舰。
具體做法是先將源文件添加到Pod/Classes中,然后按照不同的模塊對(duì)文件目錄進(jìn)行整理需了,因?yàn)槲矣兴膫€(gè)模塊跳昼,所以在Pod/Classes下有創(chuàng)建了四個(gè)子目錄,完成之后繼續(xù)編輯之前的PodTestLibrary.podspec肋乍,這次增加了subspec特性
Pod::Spec.new do |s|
s.name = "PodTestLibrary"
s.version = "1.0.0"
s.summary = "Just Testing."
s.description = <<-DESC
Testing Private Podspec.
* Markdown format.
* Don't worry about the indent, we strip it!
DESC
s.homepage = "https://coding.net/u/wtlucky/p/podTestLibrary"
# s.screenshots = "www.example.com/screenshots_1", "www.example.com/screenshots_2"
s.license = 'MIT'
s.author = { "wtlucky" => "wtlucky@foxmail.com" }
s.source = { :git => "https://coding.net/wtlucky/podTestLibrary.git", :tag => "1.0.0" }
# s.social_media_url = 'https://twitter.com/<TWITTER_USERNAME>'
s.platform = :ios, '7.0'
s.requires_arc = true
#s.source_files = 'Pod/Classes/**/*'
#s.resource_bundles = {
# 'PodTestLibrary' => ['Pod/Assets/*.png']
#}
#s.public_header_files = 'Pod/Classes/**/*.h'
s.subspec 'NetWorkEngine' do |networkEngine|
networkEngine.source_files = 'Pod/Classes/NetworkEngine/**/*'
networkEngine.public_header_files = 'Pod/Classes/NetworkEngine/**/*.h'
networkEngine.dependency 'AFNetworking', '~> 2.3'
end
s.subspec 'DataModel' do |dataModel|
dataModel.source_files = 'Pod/Classes/DataModel/**/*'
dataModel.public_header_files = 'Pod/Classes/DataModel/**/*.h'
end
s.subspec 'CommonTools' do |commonTools|
commonTools.source_files = 'Pod/Classes/CommonTools/**/*'
commonTools.public_header_files = 'Pod/Classes/CommonTools/**/*.h'
commonTools.dependency 'OpenUDID', '~> 1.0.0'
end
s.subspec 'UIKitAddition' do |ui|
ui.source_files = 'Pod/Classes/UIKitAddition/**/*'
ui.public_header_files = 'Pod/Classes/UIKitAddition/**/*.h'
ui.resource = "Pod/Assets/MLSUIKitResource.bundle"
ui.dependency 'PodTestLibrary/CommonTools'
end
s.frameworks = 'UIKit'
#s.dependency 'AFNetworking', '~> 2.3'
#s.dependency 'OpenUDID', '~> 1.0.0'
end
因?yàn)槲覀儎?chuàng)建了subspec所以項(xiàng)目整體的依賴dependency鹅颊,源文件source_files,頭文件public_header_files墓造,資源文件resource等都移動(dòng)到了各自的subspec中堪伍,每個(gè)subspec之間也可以有相互的依賴關(guān)系,比如UIKitAddition就依賴于CommonTools觅闽。
編輯完成之后杠娱,在測(cè)試項(xiàng)目里pod update一下,幾個(gè)子項(xiàng)目都被加進(jìn)項(xiàng)目工程了谱煤,寫代碼驗(yàn)證無誤之后摊求,就可以將這個(gè)工程push到遠(yuǎn)端倉庫,并打上新的tag->1.0.0刘离。
最后再次使用pod lib lint驗(yàn)證編輯好的podsepc文件室叉,沒有自身的WARNING或者ERROR之后,就可以再次提交到Spec Repo中了硫惕,命令跟之前是一樣的
$ pod repo push MySpecs PodTestLibrary.podspec
之后再次到~/.cocoapods/repos/MySpecs目錄下查看
.
├── LICENSE
├── PodTestLibrary
│ ├── 0.1.0
│ │ └── PodTestLibrary.podspec
│ └── 1.0.0
│ └── PodTestLibrary.podspec
└── README.md
3 directories, 4 files
已經(jīng)有兩個(gè)版本了茧痕,使用pod search查找得到的結(jié)果為
$ pod search PodTestLibrary
-> PodTestLibrary (1.0.0)
Just Testing.
pod 'PodTestLibrary', '~> 1.0.0'
- Homepage: https://github.com/Wanlima/podTestLibrary
- Source: https://github.com/Wanlima/podTestLibrary.git
- Versions: 1.0.0, 0.1.0 [MySpecs repo]
- Sub specs:
- PodTestLibrary/NetWorkEngine (1.0.0)
- PodTestLibrary/DataModel (1.0.0)
- PodTestLibrary/CommonTools (1.0.0)
- PodTestLibrary/UIKitAddition (1.0.0)
完成這些之后,在實(shí)際項(xiàng)目中我們就可以選擇使用整個(gè)組件庫或者是組件庫的某一個(gè)部分了恼除,對(duì)應(yīng)的Podfile中添加的內(nèi)容為
# 官方庫
$ source 'https://github.com/CocoaPods/Specs.git'
# 私有庫
$ source 'https://github.com/Wanlima/MySpecs.git'
platform :ios, '7.0'
pod 'PodTestLibrary/NetWorkEngine', '1.0.0' #使用某一個(gè)部分
pod 'PodTestLibrary/UIKitAddition', '1.0.0'
pod 'PodTestLibrary', '1.0.0' #使用整個(gè)庫
如果我們要?jiǎng)h除私有Spec Repo下的某一個(gè)podspec怎么操作呢踪旷,此時(shí)無需借助Cocoapods,只需要cd到~/.cocoapods/repos/WTSpecs目錄下豁辉,刪掉庫目錄
$ rm -Rf PodTestLibrary
然后在將Git的變動(dòng)push到遠(yuǎn)端倉庫即可
$ git add --all .
$ git ci -m "remove unuseful pods"
$ git push origin master
問題小結(jié)
- pod search 搜索不到
[!] Unable to find a pod with name, author, summary, or description matching `xxxLibary`
解決辦法:
更新本地Pod倉庫:
pod setup
刪除搜索索引:
rm ~/Libary/Caches/Cocopods/search_index.json
重新搜索
提交本地podspec到Specs倉庫的時(shí)候出錯(cuò)令野,提示repo 文件夾下的spec repo is not clean
方法一: cd到spec repo 文件夾下,執(zhí)行 git clean -f
方法二:cd到spec repo 文件夾下徽级,執(zhí)行 git stash
方法三: 刪除spec repo 下的Specs倉庫气破,我這里的是“MySpecs”,然后重新從git上將私有倉庫clone下來:
pod repo add MySpecs https://github.com/CharlsPrince/MySpecs.git