平時(shí)我們項(xiàng)目開發(fā)會(huì)抽離一些公共模塊,那么這些公共模塊如何管理呢,呵呵,搭建CocoaPods私有庫來去管理是最好不過了. 由于之前工作忙沒時(shí)間整理,最近正好有些閑暇時(shí)間,我就拋磚引玉,搭建一個(gè)簡單示例,順便梳理一下流程.
??首先是環(huán)境搭建,我采用docker里面部署一個(gè)gitlab來作為私有庫倉庫,然后拿一個(gè)示例項(xiàng)目拆分出公共模塊,接著我會(huì)把公共模塊打包成pod,最后到項(xiàng)目中引用
一 Docker安裝
二 部署gitlab
三 創(chuàng)建CocoaPods私有庫
四 更新私有庫
五 問題總結(jié)
一 Docker安裝
Docker 將應(yīng)用程序與該程序的依賴,打包在一個(gè)文件里面咐汞。運(yùn)行這個(gè)文件盖呼,就會(huì)生成一個(gè)虛擬容器。程序在這個(gè)虛擬容器里運(yùn)行化撕,就好像在真實(shí)的物理機(jī)上運(yùn)行一樣几晤。有了 Docker,就不用擔(dān)心環(huán)境問題植阴。
總體來說蟹瘾,Docker 的接口相當(dāng)簡單,用戶可以方便地創(chuàng)建和使用容器掠手,把自己的應(yīng)用放入容器憾朴。容器還可以進(jìn)行版本管理、復(fù)制惨撇、分享伊脓、修改,就像管理普通的代碼一樣”ㄇ唬總之類似于我們使用的虛擬機(jī),只能說很行,但是它不是,就是一個(gè)環(huán)境隔離工具,類似于iOS的沙盒, 關(guān)于Docker的使用我不到贅述,感興趣的可以找相關(guān)資料,我這里只用了很少一部分,很簡單.
步驟1 Docker下載地址https://www.docker.com/get-started
步驟2 我的是Mac環(huán)境,我下載的是.dmg,雙擊下載好的xx.dmg安裝,安裝好后是下面的界面
右上角的小鯨魚就正在運(yùn)行的Docker,下面我們來驗(yàn)證一下Docker是否安裝好
步驟3 驗(yàn)證Docker環(huán)境
OK Docker環(huán)境搭建就是如此簡單,接下來我們來部署gitlab
二 部署gitlab
步驟 1 在電腦機(jī)器上找一個(gè)目錄新建一個(gè)文件夾
步驟 2 在新建的目錄內(nèi)新建一個(gè)文件docker-compose.yml,名字不要改,這是一個(gè)docker編排文件,我們將要用docker-compose工具來部署它
步驟 3 編輯docker-compose.yml文件內(nèi)容,并保存,下面是文件內(nèi)容
version: '3'
services:
web:
image: 'twang2218/gitlab-ce-zh'
restart: always
hostname: '127.0.0.1'
environment:
TZ: 'Asia/Shanghai'
GITLAB_OMNIBUS_CONFIG: |
external_url 'http://127.0.0.1'
gitlab_rails['gitlab_shell_ssh_port'] = 2222
unicorn['port'] = 8888
nginx['listen_port'] = 80
ports:
- '8088:80'
- '2443:443'
- '2222:22'
volumes:
- ./config:/etc/gitlab
- ./data:/var/opt/gitlab
- ./logs:/var/log/gitlab
步驟 4 終端切換到這個(gè)文件所在目錄下,執(zhí)行如下命令
docker-compose up -d
文件大會(huì)下載一會(huì),如果你網(wǎng)速不好失敗了,那就在重新執(zhí)行這個(gè)命令,當(dāng)運(yùn)行完成后,我們載查看下是否部署好了
步驟 5 執(zhí)行命令查看容器是否創(chuàng)建運(yùn)行
docker ps | grep twang
步驟 6 訪問gitlab: http://127.0.0.1:8088/
OK出現(xiàn)這個(gè)頁面我們gitlab就搭建好了,我們可以注冊(cè)賬號(hào)(自行操作吧)登陸進(jìn)去了,接下來就開始我們的私有庫創(chuàng)建了
三 創(chuàng)建CocoaPods私有庫
在操作之前,我們先看一下我們即將要改造的項(xiàng)目大致結(jié)構(gòu)
演示項(xiàng)目本身就是用CocoaPods管理的,因?yàn)槲乙昧艘恍┑谌綆?下面我就要把紅框圈出來的公共模塊拿出來,放到私有pod里面,接下來我們按步驟一步一步來操作
首先要先區(qū)分倆概念:
Code Repository:比如我開發(fā)了一個(gè)功能模塊Tools株搔,源碼文件是保存到Code Respository的,就是我們平時(shí)用的git倉庫纯蛾。
Specs Repository:針對(duì)Tools會(huì)有一個(gè)Tools.podspec文件用來配置Tools的發(fā)布的纤房,保存podspec文件的倉庫就是Specs Repository。它保存了所有要發(fā)布的組件的podspec文件翻诉,僅用來配置炮姨,叫配置倉庫。
總結(jié)一下,我們就需要?jiǎng)?chuàng)建兩個(gè)倉庫,一個(gè)方pod代碼,一個(gè)來放podspec配置
步驟 1:創(chuàng)建代碼倉庫Code Repository
登陸上gitlab,我們點(diǎn)擊新建項(xiàng)目,然后輸入項(xiàng)目名稱,勾選README,不勾選不會(huì)自動(dòng)創(chuàng)建master分支,最后點(diǎn)create project創(chuàng)建項(xiàng)目
步驟 2:checkout Code Repository倉庫到本地~/swifttoolspod中碰煌,然后往該文件夾中添加如下內(nèi)容:
拉取代碼倉庫
本地文件夾要添加的內(nèi)容
說明:
①其中Classes為文件夾舒岸,用來存儲(chǔ)組件的源碼,這里我示例項(xiàng)目Tools目錄下的文件拷貝了過來如圖芦圾。
②SwiftTools.podspect為當(dāng)前這個(gè)組件的pod描述我們可以通過
pod spec create SwiftTools
命令來生成.podspect模版文件
我們這里的文件內(nèi)容如下
Pod::Spec.new do |spec|
spec.name = "SwiftTools"
spec.version = "1.0.3"
spec.summary = "SwiftTools 項(xiàng)目常用的工具庫"
spec.description = <<-DESC
swift 項(xiàng)目常用工具庫
DESC
spec.homepage = "http://lerpo.github.io"
spec.license = { :type => "MIT", :file => "LICENSE" }
spec.author = { "xml" => "" }
spec.platform = :ios
spec.ios.deployment_target = "10.0"
spec.source = { :git => "http://127.0.0.1:8088/xml/tools.git", :tag => "#{spec.version}" }
spec.source_files = "Classes", "Classes/**/*.{swift}"
spec.exclude_files = "Classes/Exclude"
spec.dependency 'HandyJSON', '~> 5.0.1'
spec.dependency 'SwiftyJSON'
spec.dependency 'Alamofire', '~> 5.1'
spec.dependency 'MJRefresh'
spec.dependency 'MBProgressHUD', '~> 1.2.0'
end
3 LICENSE 文件,我們?cè)诖a倉庫主頁,點(diǎn)擊添加許可證,然后選擇MIT,最后保存提交,LICENSE文件就生成了,最后我們把這個(gè)文件更新到本地倉庫
步驟 3:驗(yàn)證SwiftTools.podspec,終端進(jìn)入到SwiftTools.podspec所在目錄執(zhí)行如下命令
pod lib lint --allow-warnings
如果出現(xiàn)SwiftTools passed validation,就代表驗(yàn)證通過,如果出現(xiàn)[!] SwiftTools did not pass validation, due to 3 errors.,就代表沒通過驗(yàn)證,你要根據(jù)錯(cuò)誤?提示來修改,但所有驗(yàn)證通過后,我們就可以進(jìn)行下一步了
步驟 4:將~/swifttoolspod內(nèi)添加的四樣內(nèi)容推送到gitlab上
我這是推送過的,如果是第一次也是一樣,代碼推送到倉庫里后,我們接下來要打標(biāo)簽tag
步驟 5:給代碼倉庫創(chuàng)建tag , tag名要和上面podspec文件中spec.version的值一致蛾派。
這種操作很簡單,就是給倉庫打tag,唯一要注意??的是tag名要和上面podspec文件中spec.version的值一致 OK代碼倉庫這邊我們已經(jīng)配置完了,接下來我們配置Specs Repository倉庫
步驟 6: 創(chuàng)建配置倉庫Specs Repository
跟創(chuàng)建代碼倉庫一樣,在gitlab上創(chuàng)建一個(gè)倉庫命名為Specs个少,這個(gè)倉庫用來保存.podspec文件洪乍。空倉庫需要?jiǎng)?chuàng)建一個(gè)README文件夜焦,因?yàn)間itlab在空倉庫中是沒有分支的壳澳,加個(gè)README讓其自動(dòng)創(chuàng)建master分支
步驟 7: 配置倉庫checkout到本地~/podspec,注意??使用的是pod的命令,不是git clone
pod repo add SwiftTools http://127.0.0.1:8088/mengliang/Specs.git
步驟 8:將SwiftTools.podspec添加到配置倉庫
在代碼倉庫checkout的路徑~/podspec下面打開Terminal,執(zhí)行push命令
pod repo push Specs ../swifttoolspod/SwiftTools.podspec --allow-warnings
上面命令是將當(dāng)前目錄(/podspec)下的SwiftTools.podspec文件推送到/.cocoapods/repos目錄下SwiftTools文件夾對(duì)應(yīng)的遠(yuǎn)程倉庫中
就像下面出現(xiàn)綠色提示就代表推送成功
macbookdeMacBook-Pro:podspec mac$ pod repo push Specs ../swifttoolspod/SwiftTools.podspec --allow-warnings
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin19/rbconfig.rb:229: warning: Insecure world writable dir /usr/local/sbin in PATH, mode 040777
Validating spec
-> SwiftTools (1.0.3)
- WARN | description: The description is shorter than the summary.
- WARN | url: There was a problem validating the URL http://lerpo.github.io.
- WARN | [iOS] swift: The validator used Swift `4.0` by default because no Swift version was specified. To specify a Swift version during validation, add the `swift_versions` attribute in your podspec. Note that usage of a `.swift-version` file is now deprecated.
- NOTE | xcodebuild: note: Using new build system
- NOTE | [iOS] xcodebuild: note: Planning build
- NOTE | [iOS] xcodebuild: note: Constructing build description
- NOTE | [iOS] xcodebuild: note: Execution policy exception registration failed and was skipped: Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted" (in target 'MJRefresh' from project 'Pods')
- NOTE | [iOS] xcodebuild: note: Execution policy exception registration failed and was skipped: Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted" (in target 'SwiftyJSON' from project 'Pods')
- NOTE | [iOS] xcodebuild: note: Execution policy exception registration failed and was skipped: Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted" (in target 'MBProgressHUD' from project 'Pods')
- NOTE | [iOS] xcodebuild: note: Execution policy exception registration failed and was skipped: Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted" (in target 'HandyJSON' from project 'Pods')
- NOTE | [iOS] xcodebuild: note: Execution policy exception registration failed and was skipped: Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted" (in target 'Alamofire' from project 'Pods')
- NOTE | [iOS] xcodebuild: note: Execution policy exception registration failed and was skipped: Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted" (in target 'SwiftTools' from project 'Pods')
- NOTE | [iOS] xcodebuild: note: Execution policy exception registration failed and was skipped: Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted" (in target 'Pods-App' from project 'Pods')
- NOTE | [iOS] xcodebuild: note: Execution policy exception registration failed and was skipped: Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted" (in target 'App' from project 'App')
- NOTE | [iOS] xcodebuild: warning: Skipping code signing because the target does not have an Info.plist file and one is not being generated automatically. (in target 'App' from project 'App')
Updating the `Specs' repo
Adding the spec to the `Specs' repo
- [Fix] SwiftTools (1.0.3)
Pushing the `Specs' repo
[!] 'SwiftTools' uses the unencrypted 'http' protocol to transfer the Pod. Please be sure you're in a safe network with only trusted hosts. Otherwise, please reach out to the library author to notify them of this security issue.
OK 萬事具備了,我們開始在項(xiàng)目中使用了
步驟 9:使用私有庫,項(xiàng)目配置profile文件
總共三步操作,仔細(xì)看我圖上的標(biāo)示,接下來更新庫
步驟 10:進(jìn)入到項(xiàng)目的根目錄執(zhí)行命令
pod install
更新完依賴庫,我們就可以運(yùn)行項(xiàng)目了, 接下來我們看一下我們更新了私有庫我們?cè)撊绾尾僮?/p>
四 更新私有庫
步驟 1 修改私有庫Code Repository源碼后,我們要修改.podspec描述文件,尤其要改版本號(hào)
步驟 2驗(yàn)證文件有效性
步驟 3驗(yàn)證通過后推送到gitlab代碼倉庫
步驟 4給倉庫打個(gè)標(biāo)簽,注意??tag要跟.podspec描述文件里面的版本號(hào)一致
步驟 5 更新podspec Specs Repository倉庫,切換到本地Specs Repository倉庫執(zhí)行下面的命令
macbookdeMacBook-Pro:podspec mac$ pod repo push Specs ../swifttoolspod/SwiftTools.podspec --allow-warnings
macbookdeMacBook-Pro:podspec mac$ pod repo push Specs ../swifttoolspod/SwiftTools.podspec --allow-warnings
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin19/rbconfig.rb:229: warning: Insecure world writable dir /usr/local/sbin in PATH, mode 040777
Validating spec
-> SwiftTools (1.0.3)
- WARN | description: The description is shorter than the summary.
- WARN | url: There was a problem validating the URL http://lerpo.github.io.
- WARN | [iOS] swift: The validator used Swift `4.0` by default because no Swift version was specified. To specify a Swift version during validation, add the `swift_versions` attribute in your podspec. Note that usage of a `.swift-version` file is now deprecated.
- NOTE | xcodebuild: note: Using new build system
- NOTE | [iOS] xcodebuild: note: Planning build
- NOTE | [iOS] xcodebuild: note: Constructing build description
- NOTE | [iOS] xcodebuild: note: Execution policy exception registration failed and was skipped: Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted" (in target 'MJRefresh' from project 'Pods')
- NOTE | [iOS] xcodebuild: note: Execution policy exception registration failed and was skipped: Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted" (in target 'SwiftyJSON' from project 'Pods')
- NOTE | [iOS] xcodebuild: note: Execution policy exception registration failed and was skipped: Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted" (in target 'MBProgressHUD' from project 'Pods')
- NOTE | [iOS] xcodebuild: note: Execution policy exception registration failed and was skipped: Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted" (in target 'HandyJSON' from project 'Pods')
- NOTE | [iOS] xcodebuild: note: Execution policy exception registration failed and was skipped: Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted" (in target 'Alamofire' from project 'Pods')
- NOTE | [iOS] xcodebuild: note: Execution policy exception registration failed and was skipped: Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted" (in target 'SwiftTools' from project 'Pods')
- NOTE | [iOS] xcodebuild: note: Execution policy exception registration failed and was skipped: Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted" (in target 'Pods-App' from project 'Pods')
- NOTE | [iOS] xcodebuild: note: Execution policy exception registration failed and was skipped: Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted" (in target 'App' from project 'App')
- NOTE | [iOS] xcodebuild: warning: Skipping code signing because the target does not have an Info.plist file and one is not being generated automatically. (in target 'App' from project 'App')
Updating the `Specs' repo
Adding the spec to the `Specs' repo
- [Fix] SwiftTools (1.0.3)
Pushing the `Specs' repo
[!] 'SwiftTools' uses the unencrypted 'http' protocol to transfer the Pod. Please be sure you're in a safe network with only trusted hosts. Otherwise, please reach out to the library author to notify them of this security issue.
成功后進(jìn)入下一步操作
步驟 6 修改項(xiàng)目profile文件
步驟 7 在項(xiàng)目根目錄執(zhí)行
pod install
步驟 8 運(yùn)行項(xiàng)目
總結(jié):如果項(xiàng)目再更新,那就循環(huán)往復(fù)這8個(gè)步驟,我們可以看到這些步驟很多很繁瑣,借助CI/CD這些都可以自動(dòng)化操作(這個(gè)有時(shí)間再搞,大致就是docker部署jenkins,然后寫python腳本執(zhí)行上面的步驟操作,最后建個(gè)job構(gòu)建)
五 問題總結(jié)
1 pod代碼問題
我們從項(xiàng)目抽離出來的代碼放到私有pod倉庫,由于swift文件權(quán)限問題,并不能什么都不改就能直接引入到項(xiàng)目中使用. 我們需要修改文件權(quán)限. 這可是工作量很大的工作,做過你就知道了. 所以項(xiàng)目模塊化是很耗費(fèi)精力的
遇到的權(quán)限問題,主要是你的方法要不要公開,允不允許別人重寫
open:公開的茫经,內(nèi)部外部模塊都可訪問巷波,這個(gè)開放性最大;public:也是公開的,但還是與open有所區(qū)別科平。
open與public區(qū)別:public在只能限制在定義所在模塊內(nèi)部進(jìn)行繼承與方法的重寫褥紫,而open則是只要模塊有被import,在可在此模塊中繼承或者重寫被import進(jìn)來的模塊中的類或方法瞪慧。
2 項(xiàng)目引用問題
引入私有庫,在用法到私有庫的地方別忘了導(dǎo)入頭文件
最后我們?cè)贁U(kuò)展一下,如果我有好多個(gè)公共庫我們?cè)撊绾喂芾? 這些公共庫如果有項(xiàng)目依賴怎么辦??? 歡迎大家一起討論
最后的最后我把示例代碼貼出來:
項(xiàng)目代碼:https://github.com/lerpo/swiftproject/branches/all
項(xiàng)目運(yùn)行起來的示例圖給大家來一張,都是美女噢??