原創 2017-05-25
關鍵點:
- 組件化框架以及所需技能
- 驗證項目
- 創建私有Repo
- 創建工程
- 創建組件Pod
- 配置Jenkins-Pipeline
- 通過fastlane 創建lanes
由于最近在公司要求做關于組件化開發的事,索性就將自己如何實現一步一步的記錄下來,這里介紹如何來實現的,將會分為幾個階段介紹,現目前介紹第一階段:驗證(即驗證所需技能、Android客戶端和我們實現的技術不同時如何找出較優方案、如何與后端管理系統配合,后端需要提供哪些能力),如果有不合理的地方望指點我的郵箱。
關于為什么我們在開發移動端的時候需要使用到組件化開發呢?這里有一些我自己通過別人介紹以及自己在驗證組件化開發時的體會組件化開發之-我們有什么必要使用組件化開發?
我們后臺采用微服務架構,有能力為第三方開發者提供更多的服務,但是有時候為了適應業務需求的快速變化,以及部分客戶(如電信、移動)特殊需求(不能用我們平臺提供的服務時、不能將數據提交至第三方管理平臺等),這時候別人在開發自己的后臺時,也要求我們前端架構也能夠考慮到了可擴展開發,也就是說要求我們的架構需要能夠滿足 插件化開發(為第三方提供SDK),那么為了實現這些需求我們需要做哪些呢?
組件化框架以及所需技能
首先簡單介紹一下我們iOS組件化的架構,如下圖,整個架構會分為三個階段實現:
- 實現基礎及業務模塊組件化開發
- 封裝Framework及規范SDK接口文檔
- 團隊內首先使用SDK完成插件化開發
- [組件]: 目前我們包含了業務組件以及基礎組件。業務組件涉及到你所需要完成的某個需求,這里是根據公司業務需求進行開發;常用的網絡,數據存儲等我們把它們劃歸到基礎組件中來,但是請你記住一點,也是很重要的一點:基礎組件的開發應該是建立在業務需求的基礎之上,任何獨立開發出來的基礎組件對于業務需求來說并不會起到任何幫助作用,應該由業務需求指導基礎組件的開發,任何獨立出來的基礎組件應該是建立在你需要做的某個功能上,如上圖中提到的網絡請求、藍牙BLE、MQTT等基礎組件。
- [私有/公有倉庫]: 團隊協作開發時,我們應該也可能是必須使用到的是版本控制工具。你應該從上圖中看到,我們使用到了CocoaPods,我推薦你使用Git,當然使用SVN也沒有什么問題,但是如果你覺得你寫的公有基礎組件可以為大多數業務需求提供服務能力,想通過開源來為大家所使用,并且也從中找出不足,那么用Git是一個比較好的選擇。如果你以前使用的是SVN這個版本控制工具,而且是經常使用命令的方式來使用,相信你可以很快過渡到Git并且熟練使用,這里我的另一篇Git基礎,就應該能夠滿足你創建Pod了。
- [Pod]:相信你在開發iOS中也或多或少用過第三方依賴,也應該聽說和使用過CocoaPods,在我們的組件化架構中我們需要使用到該項技能更多一點的東西:組件化開發之-Cocoapods使用及創建發布自己的Pod以及組件化開發之-pod創建規范,我們需要能夠創建自己的公有Pod 以及私有Pod,使用過Pod之后你會發現這個第三方依賴管理工具也同樣非常適合用來進行組件化以及插件化管理。
- [Web后臺管理]:上面架構圖的Web管理后臺其實可以不存在,但是為什么這里需要考慮進組件開發框架中呢?我相信你們如果是提供微服務后臺,那么你肯定遇到過很多需要定制化業務需求,或者你在出售你自己業務的時候需要分別為不同用戶定制不同的App,而不是把你所開發的所有業務組件一起打包送你給你的客戶,這個時候你就需要用到后臺管理來根據不同用戶,不同權限,不同選擇構建你的移動應用。Web后臺管理這里僅僅為移動端提供權限、用戶自定義業務、后期用戶開發的自定義業務Pod管理、自動生成配置文件以及后續觸發自動打包功能。
- [Jenkins]:是持續集成的一個很好引擎,那么我們為什么在軟件開發中實現持續集成呢?就我現目前了解到發現,如果我們是團隊開發來完成某一下工作,那么我們就存在多次提交代碼,提交之后需要快速的驗證修改,我們不能每次提交一個就自己去為App打一次包交由測試團隊來測試吧。而且有時候我們一個需求開發完成我們遇到特殊情況需要快速上線呢?Agile教給了我們做出來的東西需要是MVP(這里不是你王者榮耀游戲中的那個最屌的隊友,也不是美國職業籃球聯賽最有價值球員獎,而是最小可運行版本),其中有一個步驟需要我們使用工具來實現,這時候我們就用到了Jenkins,我的另一片文章寫了關于如何使用:組件化開發之-基于Jenkins搭建iOS持續集成開發環境。
- [SDK/Framework]:要實現插件化開發以及平臺管理,那么你肯定得為第三方開發者提供一個可快速實現的框架以及規范吧,上圖中提到的開發業務組件/基礎組件就是我們為第三方開發公司提供的一些可以快速使用的Framework和能夠快速接入平臺的SDK,以及一些開發規范,只要按照這個開發規范來進行,那么你的需求就可以在原有的基礎之上實現特殊需求的業務,并且快速集成發布你的版本。
- [第三方開發]:你只需要按照上述提到的開發規范進行開即可,開發完成后的業務組件有兩種方式快速接入到平臺:一種是你可以將你的業務組件直接上傳或者打包成Framework,并且通過Pod方式提交到我們鎖提供的私有Pod倉庫,同時在我們的后臺按照規范提交你的組件模塊;另一種方式是可能你不喜歡讓別人看到你的代碼(即使是你的合作者),那么你可以提交到你自己的私有倉庫并且創建好你的Private Pod,告訴平臺你的倉庫地址即可。至于剩下的事情就交于平臺處理吧,你將會比你完全構建一個App花費更少的時間。
要實現插件化是需要建立在組件化的基礎之上的,這一階段我們只講述關于組件化開發相關的框架及技術,在組件化成型并穩定的情況再來考慮插件化開發。以下是我們實現整個框架的腦圖(現階段我們只做圖中右半部分):
驗證項目
上述章節已經提到了我們需要做的事以及需要了解的技術,以及我們如何分階段實現,這里就不廢話了,直接開始創建一個驗證項目。
創建私有Repo
-
在Github上創建一個Repository,并且命名為Specs(至于為什么要這樣可以參考組件化開發之-pod創建規范)
-
添加Private Pod 并驗證
現在我們添加自己私有倉庫就算成功了, 接下來就是需要來創建自己的工程。
創建工程
由于這里是驗證工程,我們就將工程命名為VerifyProject吧,同樣也需要在Github上創建工程的倉庫(因為我們后期需要通過Jenkins自動下載代碼進行配置并構建)
-
創建項目Repository
將Repository拉取下來并且通過XCode創建工程VerifyProject
-
創建配置文件Config以及Config.swift
???其實我們可以在后續通過Jenkins-Pipeline 腳本動態創建這兩個文件的,但是這里為什么需要首先創建呢?一個原因是:整項目是由哪些組件構建而成是動態的,我們需要根據Web管理后臺的配置來修改配置文件、我們主模塊的顯示以及修改Podfile。還有一個更重要的原因是:我們知道如果你在項目中動態添加任何文件,XCode是無法將其打包到你的項目中的,因為你并沒有指定它這些新創建的文件是需要編譯的,當然也有大神提出了解決方案的使用代碼為 Xcode 工程添加文件,略微有點麻煩,我們這里是驗證工程,就先跑起來再說,在后階段慢慢完善。
創建完成后,你的項目看起來應該是這樣的:
-
初始化你的Podfile,這個時候請你記住不需要在Podfile添加任何依賴
現在你的工程創建也已經完成了,現在提交到Github倉庫,它看起來應該是:
創建組件Pod
接下來就是創建你的組件Pod了,在創建組件Pod的時候我建議參考組件化開發之-pod創建規范(這僅僅是一個簡單的規范,適合小項目) 。這里我們創建5個組件模塊稱之為:VerifyA、VerifyB、VerifyC、VerifyD、VerifyE,創建方式是相同的,我以VerifyA為例。
- 在Github上創建Repository
- 創建Example,假設我們采用的是MVVM開發模式,創建好之后在UIViewcontroller中添加簡單代碼即可,最后看起來應該是:
- 創建.podspec,并且創建Pod/Classes目錄,將Example的View、ViewModel、Model拷貝至Classes目錄
$ pod spec create Verify+A
最后你的目錄結構看起來應該是:
-
修改.podspec
本地驗證.podspec是否正確
$ pod lib lint
- 提交到Github,并遠程驗證,按照下列步驟需要首先提交Git,然后添加Tag
$ git add .
$ git commit -m "添加Pod"
$ git push
# 添加Tag
$ git tag 0.0.1 # 這里需要與你.podspec中 s.version相同
$ git push --tags
# 驗證
$ pod spec lint
-> Verify+A (0.0.1)
Analyzed 1 podspec.
Verify+A.podspec passed validation.
- 添加Pod到你私有的Repo中
$ pod repo push Verify Verify+A.podspec
Validating spec
-> Verify+A (0.0.1)
Updating the `Verify' repo
Already up-to-date.
Adding the spec to the `Verify' repo
- [No change] Verify+A (0.0.1)
Pushing the `Verify' repo
Username for 'https://github.com': wangcccong@foxmail.com
Password for 'https://wangcccong@foxmail.com@github.com':
To https://github.com/ApterKingRepo/Specs.git
ea61c37..3df4c78 master -> master
- 試試搜索你的Pod
$ pod search Verify+A
-> Verify+A (0.0.1)
業務組件A
pod 'Verify+A', '~> 0.0.1'
- Homepage: https://github.com/ApterKingRepo/Verify-A
- Source: https://github.com/ApterKingRepo/Verify-A.git
- Versions: 0.0.1 [Verify repo]
- 現在你可以使用了,請記住在你的Podfile中添加你Private Pod 源
source 'https://github.com/CocoaPods/Specs'
source 'https://github.com/ApterKingRepo/Specs.git'
platform :ios, "9.0"
target "XXX" do
pod 'Verify+A', '~>0.0.1'
end
- 按照上述方法創建你的其他組件,最后創建成功之后,在你的Specs中,看到的應該是這樣
配置Jenkins-Pipeline
在使用Jenkins之前你需要去了解fastlane如何使用。我的另一篇文章有一個簡單介紹:組件化開發之-基于Jenkins搭建iOS持續集成開發環境,但是更多更詳細功能還請你移步fastlane docs。
-
New Item 創建一個Pipeline
-
配置Pipeline General
-
配置Pipeline Triggers
???我們選擇帶參數的遠程觸發,從下圖的提示中我們可以看到,你只需要訪問JENKINS_URL/job/iOS/job/Verify/build?token=TOKEN_NAME
既可以觸發了,如果你帶有參數再添加即可...?token=token&module=A,B,D
-
配置Pipeline
由于在配置Pipeline script時,我們需要依賴于fastlane,我們這里就先說一說在Pipeline中需要的幾個Stage (這里只以簡單的介紹,其他更多單元測試、功能測試等,在后面階段再來詳細介紹),注意從Jenkins2.5以后Pipeline腳本支持兩種方式,新的一種方式是創建一個Jenkinsfile,然后再來寫你的腳本,最好的方式是參考官方文檔Pipeline Syntax,已經很詳細介紹了,在這里我就不細說了。
# 偽代碼
pipeline {
enviroment {
環境變量
}
parameters {
參數配置
}
stages('配置項目') {
stage('拉取原始項目')
stage('寫入配置文件')
stage('配置Podfile')
stage('引入模塊')
stage('構建項目')
stage('部署到蒲公英')
}
post {
failure {
hook_failure #通知管理后臺,構建失敗,重新構建
}
success {
hook_success # 通知管理后臺,構建成功,用戶可以直接去下載
}
}
}
通過fastlane 創建lanes
- 創建你的fastlane
這里需要你進入我們之前創建的VerifyProject項目中,然后初始化fastlane
$ cd VerifyProject
$ fastlane init
如果是第一次使用fastlane init
,你需要按照提示信息輸入你的Apple ID 以及密碼,后面的事情就交給fastlane創建就可以了。但是有時候你會發現如果你已經使用過了fastlane init
之后,并且這時候如果你的Apple ID的密碼改變了,該怎么辦呢? fastlane tool chains 提供了一個工具credentials_manager, 這時候你只需要刪除保存的密碼:
$ fastlane fastlane-credentials remove --username xxx@xxx.com
password has been deleted.
現在你可以直接執行你的fastlane init
了,如果你想要在執行時不需要輸入密碼,你可以:
$ fastlane fastlane-credentials add --username xxx@xxx.com
Password: *********
Credential xxx@xxx.com:********* added to keychain.
成功之后你會看到如下信息
+----------------+-----------------------------+
| Summary for produce 2.35.0 |
+----------------+-----------------------------+
| app_name | VerifyProject |
| app_identifier | com.ApterKing.VerifyProject |
| username | xxxxxx@xxx.com |
| sku | 1495690xx |
| platform | ios |
| language | English |
| skip_itc | false |
| skip_devcenter | false |
| team_id | FJAP4H992E |
+----------------+-----------------------------+
- 創建你的Gemfile,你需要用到fastlane哪些工具集,如我現在的如下:
source 'https://gems.ruby-china.org/'
gem 'fastlane', '2.35.0'
gem 'gym'
gem 'xcov'
gem 'cocoapods', '1.2.1'
gem 'xcpretty'
gem 'dotenv'
- 創建一些環境配置App.env
# 項目相關
FL_PROJECT_PATH = "./VerifyProject.xcodeproj"
FL_WORKSPACE_PATH = "./VerifyProject.xcworkspace"
FL_SCHEME = "VerifyProject"
# 輸出目錄
FL_OUTPUT_ROOT_DIRECTORY = "./fastlane_build"
# 蒲公英
FL_PGYER_USER_KEY = "6fe2235f85a756314753774cee5fb164"
FL_PGYER_API_KEY = "43ce06e684f029fe3ec64a436c2a5c15"
- 修改Fastfile,創建lanes,我主要有:
???在創建lane config_generate、config_pod這幾個模塊中我們需要用到shell腳本,你可以從這里去了解一下基礎的shell腳本寫法:Shell 教程
// 進入到fastlane目錄下
$ bundle exec fastlane lanes
--------- ios---------
----- fastlane ios config_generate
生成配置文件
Usage: bundle exec fastlane ios config_generate param:[數據/URL等]
----- fastlane ios config_pod
配置Podfile
Usage: bundle exec fastlane ios config_pod
----- fastlane ios build
構建項目
Usage: bundle exec fastlane ios build config:[Debug/Release]
----- fastlane ios deploy
部署到蒲公英
Usage: bundle exec fastlane ios deploy config:[Debug/Release]
- 準備工作已經做好,還記得我們前面提到的Pipeline script是使用偽代碼表示的嗎?現在我們需要來完善它,以下是我寫的:
pipeline {
agent any // 你也可以使用 agent {label 'mac_for_iOS'}
environment {
BASH_PROFILE = '~/.bashrc'
}
stages {
stage('拉取項目') {
steps {
git 'https://github.com/ApterKingRepo/VerifyProject.git'
}
}
stage('生成配置文件') {
steps {
dir('./VerifyProject/fastlane') {
sh "bundle exec fastlane ios config_generate param:'${params.module}'"
}
}
}
stage('配置Podfile') {
steps {
dir('./VerifyProject/fastlane') {
sh 'bundle exec fastlane ios config_pod'
}
}
}
stage('構建項目') {
steps {
dir('./VerifyProject/fastlane') {
sh 'bundle exec fastlane ios build config:Debug'
}
}
}
stage('部署項目') {
steps {
dir('./VerifyProject/fastlane') {
sh 'bundle exec fastlane ios deploy config:Debug'
}
}
}
}
post {
failure {
echo '構建失敗,你可以調用遠程通知,或者發送一個Email'
}
success {
echo '構建成功,你可以調用遠程通知,或者發送一個Email'
}
}
}
-
最后你需要來觸發你的Pipeline了,由于我們現在是測試,沒有與Web端鏈接,但是也能夠模擬遠程傳遞參數觸發:
-
最后你想到的應該是Build就ok 了對吧?那么你應該是想錯了,你會看到的是:
各種錯誤,也不要擔心,慢慢修改即可,最后你總會看到構建成功,我將這個整個的構建過程發布到了Github上了, 你可以從: 業務組件B
...
你可以講代碼下載來自己照著做一遍,應該就會比較熟悉整個流程,這里面的代碼還沒有考慮到如何進行業務組件間的調用,我將在下一階段來介紹
** 這里也有一點公有Pod代碼,你也可以來看看:**
最后你會發現:最快熟悉的方式應該是自己做一遍,你會發現里面有很多坑,踩多了你也就會了。