###### tags: `iOS 筆記` # 如何將自己寫的套件上傳到 CocoaPods ## 確認你要建的套件名稱是否存在 在建套件之前,先到 [CocoaPods](https://cocoapods.org/) 網站上搜尋一下,你要建的套件名稱是不是已經有人用了 ![](https://i.imgur.com/OgV9khb.png) 還有就是 CocoaPods 驗證套件的時候,似乎不會去判定套件名稱內的英文大小寫 只會看名稱是否一樣,像是下面這個例子 ``` PodLib 跟 podlib // CocoaPods 會把這兩個判定成一模一樣的套件名稱 ``` ## 建立 git repo 就一般的建立 git repo,嗯對 README.md、.gitignore、LICENSE 都不用勾 因為後面在建立 pod lib 的時候,會自己建立 ## 建立 pod lib 打開 Terminal (終端機),先 cd 到要創建 pod lib 的位置 這邊以桌面為例 ``` cd Desktop # 將當前路徑位置切到桌面 pwd # 顯示當前路徑位置 ``` 輸入完後,會長得像下面這張圖一樣 ![](https://i.imgur.com/CAQtEuL.png) 接著輸入下面這個指令來建立 pod lib ``` pod lib create <你要創建的套件名稱> 例:pod lib create MyFirstPodLib ``` 接著,就會開始詢問你一些關於建立這個套件的資訊 ```ruby= # 不負責翻譯:你這個套件是要給哪個平台所使用的??[ iOS / macOS ] What platform do you want to use?? [ iOS / macOS ] > iOS # 不負責翻譯:你這個套件是要使用哪種語言來開發??[ Swift / ObjC ] What language do you want to use?? [ Swift / ObjC ] > Swift # 不負責翻譯:你是否想要建立一個使用這個套件的範例程式?[ Yes / No ] Would you like to include a demo application with your library? [ Yes / No ] > Yes # 不負責翻譯:你要使用哪種測試框架?[ Quick / None ] Which testing frameworks will you use? [ Quick / None ] > None # 不負責翻譯:你是否想要使用 UI 測試?[ Yes / No ] Would you like to do view based testing? [ Yes / No ] > No # 不負責翻譯:你 class 的字首是什麼? # 這個只有使用 ObjC 開發的才會詢問 What is your class prefix? > ``` ![](https://i.imgur.com/BohZ16q.png) 都回答完之後,就會自動建立好一個 .xcworkspace 的檔案,並開啟 以這裡為例的話,就是 MyFirstPodLib.xcworkspace 這個檔案 **(紅框處)** 然後這個檔案會出現在 Example 資料夾裡面 ![](https://i.imgur.com/V0fihvC.png) 開啟後,會看到下面這些檔案 ![](https://i.imgur.com/lpW3foR.png) 我們在開發這個套件的時候,只會需要動下半部,也就是 Development Pods 這邊 接著先將 ReplaceMe.swift 刪掉,再將「Assets、Classes」這兩個資料夾加入 ![](https://i.imgur.com/Ijl5tFk.png) 接著再將兩個資料夾內的「.gitkeep」刪掉 然後要來說「Assets、Classes」這兩個資料夾是要用來做什麼的 Assets:用來放圖片、Color Set 等資源的 Classes:用來放 Source Code 的 首先,先在 Assets 裡面新增一個「Asset Catalog」,名稱自取~ ![](https://i.imgur.com/5huq4iN.png) 這裡我是取名為 MyFirstPodLib.xcassets ![](https://i.imgur.com/sCpAXUQ.png) 接著就可以在這裡面放圖片、Color Set 等資源了 ![](https://i.imgur.com/rmJghU4.png) 再來是 Classes,這裡面要放我們這個套件的 Source Code 在 Classes 裡面可以新增資料夾來做分類,但不要分太多層 不然有可能後面在寫 podspec 的時候會一直 match 不到檔案 (至少我是這樣啦,可能我當時在研究的時候,路徑規則一直給錯) ``The `source_files` pattern did not match any file`` 這邊我是直接在 Classes 資料夾裡面新增一個 swift 檔,叫做 TestFunc.swift ![](https://i.imgur.com/9kaf4AE.png) 然後關於 SDK 內檔案的寫法,可以去看先前我寫的這篇筆記 [Swift Framework 封裝 (基本款)](https://hackmd.io/@leoho0722/rkLYQXP-c) 這裡就用兩個簡單的 func 來示範 ```swift= import Foundation public class TestFunc { public static func sayHello() { print("MyFirstPodLib say Hello!") } public static func inputAndOutput(input: String?) { print("MyFirstPodLib:You input \(String(describing: input)), and I output \(String(describing: input))") } } ``` ![](https://i.imgur.com/3Ou3n92.png) ## 撰寫 podspec 接著要來撰寫最困難的東西了!就是 podspec! ```ruby= Pod::Spec.new do |s| s.name = 'MyFirstPodLib' s.version = '0.1.0' s.summary = 'A short description of MyFirstPodLib.' s.description = "" s.homepage = 'https://github.com/leoho0722/MyFirstPodLib' # s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2' s.license = { :type => 'MIT', :file => 'LICENSE' } s.author = { 'leoho0722' => 'leo160918@gmail.com' } s.source = { :git => 'https://github.com/leoho0722/MyFirstPodLib.git', :tag => s.version.to_s } # s.social_media_url = 'https://twitter.com/<TWITTER_USERNAME>' s.ios.deployment_target = '9.0' s.source_files = 'MyFirstPodLib/Classes/**/*' # s.resource_bundles = { # 'MyFirstPodLib' => ['MyFirstPodLib/Assets/*.png'] # } # s.public_header_files = 'Pod/Classes/**/*.h' # s.frameworks = 'UIKit', 'MapKit' # s.dependency 'AFNetworking', '~> 2.3' end ``` 下面來一一解釋這些是代表什麼意思 ```ruby= Pod::Spec.new do |s| # s 是代表下面每個屬性的前綴,可以自行修改,像是改成 spec s.name # 套件名稱,會預設以你 pod lib create 時輸入的名稱帶入 s.version # 套件版本,預設為 0.1.0,可以自行修改,像是改成 0.0.1,但是要與 git 上的 tag 一致 s.summary # 套件簡述,簡單敘述這個套件的用途,會出現在 CocoaPods 的搜尋結果上 s.description # 套件完整敘述,詳細說明這個套件的功能、用途之類的 s.homepage # 套件的主頁,通常會是 Github 網址 or 官方介紹 s.license # 套件的開源授權方式,像是 MIT、APACHE、APACHE 2.0,授權方式一定要加,不然 podspec 驗證的時候會叫你補 s.author # 套件的作者名稱及其的 Email s.source # 套件的 git 存放位置及其對應版本,tag 裡面的版本必須與 s.version 一致 s.ios.deployment_target # 套件最低支援的 iOS 系統版本 s.source_files # 套件的 Source Code 路徑,路徑規則要寫對,才會找得到檔案!!!!! s.resource_bundles # 套件裡面的圖片、Color Set 等資源,路徑規則要寫對,才會找得到檔案!!!!! s.frameworks # 套件裡面有用到 Apple 官方 Framework 名稱,要寫在這 s.dependency # 套件內如果有用到第三方套件的話,要寫在這裡 (套件名稱 跟 套件版本) end # 有開始就會有結束,end 跟 Pod::Spec.new do 是一對的 ``` 當然 podspec 裡面還有其他選項可以加入,這邊就不一一詳述了 ## 驗證 podspec podspec 寫完之後,就要來做驗證的動作了 驗證前,要先確保當前路徑下有 podspec 檔案 如果不確定的話,可以先在 Terminal 輸入 `ls` 來確認 ![](https://i.imgur.com/n9bYrT2.png) 驗證有分兩種,一種是本地驗證,一種是連網驗證 ``` 本地驗證:pod lib lint 連網驗證:pod spec lint ``` 本地驗證,顧名思義就是用本地的檔案來做驗證,不會使用 git 上面的檔案做驗證 連網驗證,顧名思義就是會用 git 上的檔案來做驗證 建議是先在本地驗證完,確認都沒有 Error,顯示綠色的 `passed validation` 在做連網驗證,連網驗證也確認都沒有 Error,顯示綠色的 `passed validation` 才將套件推上 CocoaPods 上 如果驗證過程中有出現 WARNINGS 的話,是可以被允許的,但是**絕對不能出現 ERROR** 但一般驗證的時候,就算出現 WARNINGS 也會出現驗證失敗 剛剛有說到,出現 WARNINGS 是可以被允許的 那要如何被允許呢,在指令後面多加上 `--allow-warnings` 就可以了 ``` 本地驗證:pod lib lint --allow-warnings 連網驗證:pod spec lint --allow-warnings ``` 如果要看驗證時的詳細過程,可以在指令後面多加上 `--verbose` ``` 本地驗證:pod lib lint --verbose 連網驗證:pod spec lint --verbose ``` 如果要同時允許 WARNINGS 跟看詳細過程的話,則是像下面這樣 ``` 本地驗證:pod lib lint --allow-warnings --verbose 連網驗證:pod spec lint --allow-warnings --verbose ``` 如果驗證過程中,一直出現神秘錯誤的話,可以嘗試看看下面這個指令 ``` # 將全部 pod 快取清掉 pod cache clean --all ``` 如果本地驗證失敗的話,會告訴你哪邊有錯 以下面這張為例就是,他用 podspec 裡面的 resource_bundles 檔案路徑規則,無法配對到任何檔案 所以我們就可以再去檢查一下 podspec 裡面的路徑是不是有誤 ![](https://i.imgur.com/Scm2bQG.png) 修改完之後,再次本地驗證,如果驗證成功的話, 會顯示綠色的 `passed validation`,那就代表改對了 (下圖 上半部的紅色是前面的 resource_bundles 錯誤,下半部的綠色是修改後的) ![](https://i.imgur.com/TsWcdJs.png) 接著就可以將檔案 push 到 git repo 上了,詳細步驟請參考[下面「做連網驗證前要做的事」內的說明](#做連網驗證前要做的事) 本地驗證成功後,接著就要做連網驗證了~ 連網驗證成功後,會顯示綠色的 `passed validation` ![](https://i.imgur.com/qRsGsfJ.png) 本地驗證、連網驗證都確定成功後,就可以將套件上傳到 CocoaPods 上了 ### 做連網驗證前要做的事 前面有說到連網驗證是會從 git 上取得檔案來做驗證 那 git 上的檔案是從哪來的~當然是我們把檔案 push 上去啊~ ``` git status # 用來確認更動了什麼檔案 git add . git commit -m "<你這次修改的內容>" git remote add origin <你套件的 git 連結,就是 podspec 裡面的 source> git push --set-upstream origin master # 第一次 push 會需要初始化遠端 git repo,來進行追蹤,後續只要用 git push 即可 以我的為例,就是 git status git add . git commit -m "MyFirstPodLib v0.0.1" git remote add origin https://github.com/leoho0722/MyFirstPodLib.git git push --set-upstream origin master ``` 把檔案 push 上 git 後,就要來新增 tag 了,這樣後面在做連網驗證的時候,才有辦法找到對應的套件版本 ``` git tag <你這次 podspec 裡面的 version> git push --tags 以我的為例,就是 git tag 0.0.1 git push --tags ``` ![](https://i.imgur.com/mFAyLRa.png) 啊如果 tag 打錯想刪除的話,可以這樣打 ``` git tag -d <你要刪除的 tag> ``` ## 推上 CocoaPods 要推上 CocoaPods 前,要先有 CocoaPods 的帳號 如果是先前就有用你現在在用的那台電腦註冊 Session 的話,可以輸入下面這個指令來確認 ``` pod trunk me ``` ![](https://i.imgur.com/sQzivFU.png) 如果是還沒註冊,或是有換電腦的話,那就是要重新註冊 Session ![](https://i.imgur.com/3vzdo1I.png) 所以推上的第一步就是註冊 CocoaPods 帳號 ``` pod trunk register <你的 Email> '<你的暱稱>' 以我的為例,就是 pod trunk register leo160918@gmail.com 'LeoHo' ``` ![](https://i.imgur.com/oPLGSKX.png) 註冊之後,會寄一封信到你的 Email 裡,點信中的連結來啟動這台電腦跟你的 pod trunk 帳號的連結 ![](https://i.imgur.com/9GmLvsT.png) 接著輸入下面這個指令,就可以將套件推上 CocoaPods 了 ``` pod trunk push <套件名稱>.podspec 以我的為例,就是 pod trunk push MyFirstPodLib.podspec ``` 如果上傳過程中有出現 WARNINGS 的話,是可以被允許的,但是**絕對不能出現 ERROR** 但一般上傳的時候,就算出現 WARNINGS 也會出現上傳失敗 剛剛有說到,出現 WARNINGS 是可以被允許的 那要如何被允許呢,在指令後面多加上 `--allow-warnings` 就可以了 ``` pod trunk push <套件名稱>.podspec --allow-warnings 以我的為例,就是 pod trunk push MyFirstPodLib.podspec --allow-warnings ``` 如果要看上傳時的詳細過程,可以在指令後面多加上 `--verbose` ``` pod trunk push <套件名稱>.podspec --verbose 以我的為例,就是 pod trunk push MyFirstPodLib.podspec --verbose ``` 如果要同時允許 WARNINGS 跟看詳細過程的話,則是像下面這樣 ``` pod trunk push <套件名稱>.podspec --allow-warnings --verbose 以我的為例,就是 pod trunk push MyFirstPodLib.podspec --allow-warnings --verbose ``` 這樣就可以將套件上傳到 CocoaPods 上了 ![](https://i.imgur.com/od4QzmH.png) 那要多久才能在 CocoaPods 上找到呢?阿災~(CocoaPods 官方是說 15 分鐘啦) 可能半天~一天吧,至少我是這樣啦 ## 將 Pod 套件從 CocoaPods 下架 如果某天想要將 Pod 套件從 CocoaPods 下架 有兩種做法,一種是 deprecate (棄用,**官方推薦**),一種是 delete (刪除) 要注意的是,delete 行為是不可逆的,此外 delete 的版本號是不能重複使用 兩種做法對應的 pod 指令為 ``` pod trunk deprecate <套件名稱> 例:pod trunk deprecate SeknovaSDK ``` ``` pod trunk delete <套件名稱> <套件版本> 例:pod trunk delete SeknovaSDK 0.0.17.1 ``` ## 更新套件的流程 有推出,就會有更新 所以這裡就要來講説,當要更新套件的時候,要怎麼來更新 更新流程如下 ``` 步驟1:更新 Source Code、圖片、Color Set 等檔案 步驟2:更新 podspec 內容 (像是 version 等之類的) 步驟3:pod lib lint 本地驗證 podspec (其他輔助指令,請參考前面說明) 步驟4:將更新過後的套件 git 到 git repo 步驟5:git tag <新版號>,將 git tag 更新成 podspec 內的 version 版號 步驟6:git push --tags,將新版號 push 到 git repo 步驟7:pod spec lint 連網驗證 podspec (其他輔助指令,請參考前面說明) 步驟8:pod trunk push <套件名稱>.podspec (其他輔助指令,請參考前面說明) 步驟9:測試是否可以 pod install --repo-update (需等待 CocoaPods,官方是說 15 分鐘啦) 步驟10 (optional):修改 README.md ``` ## 新增套件的流程 這邊也整理一下新增套件的流程 ``` 步驟0:先在 CocoaPods.org 上搜尋是否存在你想要創建的套件名稱 步驟1:先建立一個要用來存放套件的 git repo 步驟2:用 Terminal 切到你要建立套件專案的路徑 步驟3:在 Terminal 輸入 pod lib create <套件名稱> # 套件名稱建議與 git repo 一致 步驟4:填寫 Terminal 內詢問的套件相關資訊 步驟5:將 Assets、Classes 資料夾加入 xcworkspace (詳細加入位置,請參考前面說明), 並將 ReplaceMe.swift、.gitkeep 檔案刪除 步驟6:將 Source Code 放入 Classes 資料夾內,圖片、Color Set 等資源放入 Assets 資料夾內 步驟7:撰寫 podspec 步驟8:在 Terminal 內輸入 pod lib lint 來進行 podspec 本地驗證 (其他輔助指令,請參考前面說明), podspec 本地驗證成功後,繼續步驟9,未通過的話,回到步驟7 檢查 podspec 步驟9:當 podspec 本地驗證通過後,將 Source Code 上傳到 git repo (詳細步驟,請參考前面說明) 步驟10:為剛剛上傳到 git repo 的套件新增 git tag (tag 需與 podspec 內的 version 一致,詳細步驟,請參考前面說明) 步驟11:在 Terminal 內輸入 pod spec lint 來進行 podspec 連網驗證 (其他輔助指令,請參考前面說明), podspec 連網驗證成功後,繼續步驟12,未通過的話,回到步驟7 檢查 podspec 步驟12:在 Terminal 輸入 pod trunk me 確認該電腦是否有建立過 pod trunk Session, 有的話,跳至步驟14,沒有的話,繼續步驟13 步驟13 (optional):如果 pod trunk me 無顯示曾經建立的 Session, 則在 Terminal 輸入 pod trunk register <你的 Email> '<你的暱稱>' 步驟14:在 Terminal 輸入 pod trunk push <套件名稱>.podspec (其他輔助指令,請參考前面說明) 步驟15:測試是否可以 pod install --repo-update (需等待 CocoaPods,官方是說 15 分鐘啦) 步驟16 (optional):修改 README.md ``` ## 新增/移除 Pod 擁有者 如果是一人開發一個 Pod 套件的話,那擁有者只會有一個 (你自己) 但如果是多人開發一個 Pod 套件或是要將 Pod 套件移交給其他開發團隊的話 那就會需要進行新增 / 移除 Pod 擁有者的動作了 ### 新增 Pod 擁有者 Pod 新擁有者要做的事 ↓ ``` 步驟1:開啟 Terminal 步驟2:將 Pod 套件的 Git Repo Clone 回本地 步驟3:cd 到 Pod 套件專案目錄底下 步驟4:在 Terminal 輸入 pod trunk register <新擁有者的 Email> <新擁有者的 Name> 步驟5:到你輸入的 Email 收信來啟用 pod trunk Session 步驟6:等 Pod 原擁有者把你加入擁有者後,輸入 pod trunk me 步驟7:就可以看到被加入 Pod 套件的擁有者了 步驟8:等原擁有者把新擁有者加入 Pod 套件 Git Repo 的 Collaborators 後, 新擁有者就可以將 Code 推上 Pod 套件 Git Repo 了 ``` Pod 原擁有者要做的事 ↓ ``` 步驟1:開啟 Terminal 步驟2:cd 到 Pod 套件專案目錄底下 步驟3:在 Terminal 輸入 pod trunk add-owner <套件名稱> <新擁有者的 Email> 步驟4:在 Terminal 輸入 pod trunk info <套件名稱> 步驟5:就可以看到新加入 Pod 套件的擁有者了 步驟6:將新擁有者加入 Pod 套件 Git Repo 的 Collaborators ``` ### 移除 Pod 擁有者 移除 Pod 擁有者就比較簡單了 ``` 步驟1:步驟1:開啟 Terminal 步驟2:cd 到 Pod 套件專案目錄底下 步驟3:在 Terminal 輸入 pod trunk remove-owner <套件名稱> <要移除的擁有者的 Email> ``` ## 參考資料 > 1. <https://www.twblogs.net/a/5ee76fc8ab95e1fe834cf971> > 2. <https://www.jianshu.com/p/f841e248bc4f> > 3. <https://www.jianshu.com/p/1f70f1176727> > 4. <https://www.jianshu.com/p/c83e8228f50c> > 5. <https://www.gushiciku.cn/pl/pFL4/zh-tw> > 6. <https://www.kancloud.cn/god-is-coder/cocoapods/804799> > 7. <https://youtu.be/_u1CGl7-ta0> > 8. <https://youtu.be/vSMmZxmKIA4> > 9. <https://note.leodev.me/2016/04/05/CocoaPods-API-Elaborate-pod-trunk/> > 10. <https://guides.cocoapods.org/terminal/commands.html#group_trunk>