制作 CocoaPods 開源庫

CocoaPods 開源庫的制作過程:

  1. 添加私有Pod倉庫迷帜,用來存儲(chǔ)私有Pod庫的podspec文件物舒,類似CocoaPods的官方repo庫(~/.cocoapods/repos)
  2. 創(chuàng)建私有Pod庫的podspec文件(分全新創(chuàng)建和已存在工程兩種情況)
  3. 編輯podspec文件
  4. 測(cè)試podspec文件是否可用
  5. 本地測(cè)試podspec文件
  6. 向私有Pod庫提交podspec文件
  7. 添加到CocoaPods 官方庫
  8. 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é)

  1. pod search 搜索不到
[!] Unable to find a pod with name, author, summary, or description matching `xxxLibary`

解決辦法:

  1. 更新本地Pod倉庫:
    pod setup

  2. 刪除搜索索引:
    rm ~/Libary/Caches/Cocopods/search_index.json

  3. 重新搜索

  4. 提交本地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
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市餐抢,隨后出現(xiàn)的幾起案子现使,更是在濱河造成了極大的恐慌低匙,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,602評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件碳锈,死亡現(xiàn)場(chǎng)離奇詭異顽冶,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)售碳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門渗稍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人团滥,你說我怎么就攤上這事竿屹。” “怎么了灸姊?”我有些...
    開封第一講書人閱讀 152,878評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵拱燃,是天一觀的道長。 經(jīng)常有香客問我力惯,道長碗誉,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,306評(píng)論 1 279
  • 正文 為了忘掉前任父晶,我火速辦了婚禮哮缺,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘甲喝。我一直安慰自己尝苇,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評(píng)論 5 373
  • 文/花漫 我一把揭開白布埠胖。 她就那樣靜靜地躺著糠溜,像睡著了一般。 火紅的嫁衣襯著肌膚如雪直撤。 梳的紋絲不亂的頭發(fā)上非竿,一...
    開封第一講書人閱讀 49,071評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音谋竖,去河邊找鬼红柱。 笑死,一個(gè)胖子當(dāng)著我的面吹牛蓖乘,可吹牛的內(nèi)容都是我干的锤悄。 我是一名探鬼主播,決...
    沈念sama閱讀 38,382評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼驱敲,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼铁蹈!你這毒婦竟也來了宽闲?” 一聲冷哼從身側(cè)響起众眨,我...
    開封第一講書人閱讀 37,006評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤握牧,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后娩梨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體沿腰,經(jīng)...
    沈念sama閱讀 43,512評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評(píng)論 2 325
  • 正文 我和宋清朗相戀三年狈定,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了颂龙。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,094評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡纽什,死狀恐怖措嵌,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情芦缰,我是刑警寧澤企巢,帶...
    沈念sama閱讀 33,732評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站让蕾,受9級(jí)特大地震影響浪规,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜探孝,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評(píng)論 3 307
  • 文/蒙蒙 一笋婿、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧顿颅,春花似錦缸濒、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至栖疑,卻和暖如春讨永,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背遇革。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評(píng)論 1 262
  • 我被黑心中介騙來泰國打工卿闹, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人萝快。 一個(gè)月前我還...
    沈念sama閱讀 45,536評(píng)論 2 354
  • 正文 我出身青樓锻霎,卻偏偏與公主長得像,于是被迫代替她去往敵國和親揪漩。 傳聞我的和親對(duì)象是個(gè)殘疾皇子旋恼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評(píng)論 2 345