原創(chuàng) 2017-05-25
關(guān)鍵點(diǎn):
- 組件化框架以及所需技能
- 驗(yàn)證項(xiàng)目
- 創(chuàng)建私有Repo
- 創(chuàng)建工程
- 創(chuàng)建組件Pod
- 配置Jenkins-Pipeline
- 通過fastlane 創(chuàng)建lanes
由于最近在公司要求做關(guān)于組件化開發(fā)的事库倘,索性就將自己如何實(shí)現(xiàn)一步一步的記錄下來蠢壹,這里介紹如何來實(shí)現(xiàn)的缀旁,將會分為幾個階段介紹,現(xiàn)目前介紹第一階段:驗(yàn)證(即驗(yàn)證所需技能细办、Android客戶端和我們實(shí)現(xiàn)的技術(shù)不同時如何找出較優(yōu)方案、如何與后端管理系統(tǒng)配合砌左,后端需要提供哪些能力)住闯,如果有不合理的地方望指點(diǎn)我的郵箱。
關(guān)于為什么我們在開發(fā)移動端的時候需要使用到組件化開發(fā)呢拂酣?這里有一些我自己通過別人介紹以及自己在驗(yàn)證組件化開發(fā)時的體會組件化開發(fā)之-我們有什么必要使用組件化開發(fā)秋冰?
我們后臺采用微服務(wù)架構(gòu),有能力為第三方開發(fā)者提供更多的服務(wù)婶熬,但是有時候?yàn)榱诉m應(yīng)業(yè)務(wù)需求的快速變化剑勾,以及部分客戶(如電信埃撵、移動)特殊需求(不能用我們平臺提供的服務(wù)時、不能將數(shù)據(jù)提交至第三方管理平臺等)虽另,這時候別人在開發(fā)自己的后臺時暂刘,也要求我們前端架構(gòu)也能夠考慮到了可擴(kuò)展開發(fā),也就是說要求我們的架構(gòu)需要能夠滿足 插件化開發(fā)(為第三方提供SDK)捂刺,那么為了實(shí)現(xiàn)這些需求我們需要做哪些呢谣拣?
組件化框架以及所需技能
首先簡單介紹一下我們iOS組件化的架構(gòu),如下圖族展,整個架構(gòu)會分為三個階段實(shí)現(xiàn):
- 實(shí)現(xiàn)基礎(chǔ)及業(yè)務(wù)模塊組件化開發(fā)
- 封裝Framework及規(guī)范SDK接口文檔
- 團(tuán)隊(duì)內(nèi)首先使用SDK完成插件化開發(fā)
- [組件]: 目前我們包含了業(yè)務(wù)組件以及基礎(chǔ)組件森缠。業(yè)務(wù)組件涉及到你所需要完成的某個需求,這里是根據(jù)公司業(yè)務(wù)需求進(jìn)行開發(fā)仪缸;常用的網(wǎng)絡(luò)贵涵,數(shù)據(jù)存儲等我們把它們劃歸到基礎(chǔ)組件中來,但是請你記住一點(diǎn)腹殿,也是很重要的一點(diǎn):基礎(chǔ)組件的開發(fā)應(yīng)該是建立在業(yè)務(wù)需求的基礎(chǔ)之上独悴,任何獨(dú)立開發(fā)出來的基礎(chǔ)組件對于業(yè)務(wù)需求來說并不會起到任何幫助作用,應(yīng)該由業(yè)務(wù)需求指導(dǎo)基礎(chǔ)組件的開發(fā)锣尉,任何獨(dú)立出來的基礎(chǔ)組件應(yīng)該是建立在你需要做的某個功能上,如上圖中提到的網(wǎng)絡(luò)請求决采、藍(lán)牙BLE自沧、MQTT等基礎(chǔ)組件。
- [私有/公有倉庫]: 團(tuán)隊(duì)協(xié)作開發(fā)時树瞭,我們應(yīng)該也可能是必須使用到的是版本控制工具拇厢。你應(yīng)該從上圖中看到,我們使用到了CocoaPods晒喷,我推薦你使用Git孝偎,當(dāng)然使用SVN也沒有什么問題,但是如果你覺得你寫的公有基礎(chǔ)組件可以為大多數(shù)業(yè)務(wù)需求提供服務(wù)能力凉敲,想通過開源來為大家所使用衣盾,并且也從中找出不足,那么用Git是一個比較好的選擇爷抓。如果你以前使用的是SVN這個版本控制工具势决,而且是經(jīng)常使用命令的方式來使用,相信你可以很快過渡到Git并且熟練使用蓝撇,這里我的另一篇Git基礎(chǔ)果复,就應(yīng)該能夠滿足你創(chuàng)建Pod了。
- [Pod]:相信你在開發(fā)iOS中也或多或少用過第三方依賴渤昌,也應(yīng)該聽說和使用過CocoaPods虽抄,在我們的組件化架構(gòu)中我們需要使用到該項(xiàng)技能更多一點(diǎn)的東西:組件化開發(fā)之-Cocoapods使用及創(chuàng)建發(fā)布自己的Pod以及組件化開發(fā)之-pod創(chuàng)建規(guī)范走搁,我們需要能夠創(chuàng)建自己的公有Pod 以及私有Pod,使用過Pod之后你會發(fā)現(xiàn)這個第三方依賴管理工具也同樣非常適合用來進(jìn)行組件化以及插件化管理迈窟。
- [Web后臺管理]:上面架構(gòu)圖的Web管理后臺其實(shí)可以不存在私植,但是為什么這里需要考慮進(jìn)組件開發(fā)框架中呢?我相信你們?nèi)绻翘峁┪⒎?wù)后臺菠隆,那么你肯定遇到過很多需要定制化業(yè)務(wù)需求兵琳,或者你在出售你自己業(yè)務(wù)的時候需要分別為不同用戶定制不同的App,而不是把你所開發(fā)的所有業(yè)務(wù)組件一起打包送你給你的客戶骇径,這個時候你就需要用到后臺管理來根據(jù)不同用戶躯肌,不同權(quán)限,不同選擇構(gòu)建你的移動應(yīng)用破衔。Web后臺管理這里僅僅為移動端提供權(quán)限清女、用戶自定義業(yè)務(wù)、后期用戶開發(fā)的自定義業(yè)務(wù)Pod管理晰筛、自動生成配置文件以及后續(xù)觸發(fā)自動打包功能嫡丙。
- [Jenkins]:是持續(xù)集成的一個很好引擎,那么我們?yōu)槭裁丛谲浖_發(fā)中實(shí)現(xiàn)持續(xù)集成呢读第?就我現(xiàn)目前了解到發(fā)現(xiàn)曙博,如果我們是團(tuán)隊(duì)開發(fā)來完成某一下工作,那么我們就存在多次提交代碼怜瞒,提交之后需要快速的驗(yàn)證修改父泳,我們不能每次提交一個就自己去為App打一次包交由測試團(tuán)隊(duì)來測試吧。而且有時候我們一個需求開發(fā)完成我們遇到特殊情況需要快速上線呢吴汪?Agile教給了我們做出來的東西需要是MVP(這里不是你王者榮耀游戲中的那個最屌的隊(duì)友惠窄,也不是美國職業(yè)籃球聯(lián)賽最有價值球員獎,而是最小可運(yùn)行版本)漾橙,其中有一個步驟需要我們使用工具來實(shí)現(xiàn)杆融,這時候我們就用到了Jenkins,我的另一片文章寫了關(guān)于如何使用:組件化開發(fā)之-基于Jenkins搭建iOS持續(xù)集成開發(fā)環(huán)境霜运。
- [SDK/Framework]:要實(shí)現(xiàn)插件化開發(fā)以及平臺管理脾歇,那么你肯定得為第三方開發(fā)者提供一個可快速實(shí)現(xiàn)的框架以及規(guī)范吧,上圖中提到的開發(fā)業(yè)務(wù)組件/基礎(chǔ)組件就是我們?yōu)榈谌介_發(fā)公司提供的一些可以快速使用的Framework和能夠快速接入平臺的SDK觉渴,以及一些開發(fā)規(guī)范介劫,只要按照這個開發(fā)規(guī)范來進(jìn)行,那么你的需求就可以在原有的基礎(chǔ)之上實(shí)現(xiàn)特殊需求的業(yè)務(wù)案淋,并且快速集成發(fā)布你的版本座韵。
- [第三方開發(fā)]:你只需要按照上述提到的開發(fā)規(guī)范進(jìn)行開即可,開發(fā)完成后的業(yè)務(wù)組件有兩種方式快速接入到平臺:一種是你可以將你的業(yè)務(wù)組件直接上傳或者打包成Framework,并且通過Pod方式提交到我們鎖提供的私有Pod倉庫誉碴,同時在我們的后臺按照規(guī)范提交你的組件模塊宦棺;另一種方式是可能你不喜歡讓別人看到你的代碼(即使是你的合作者),那么你可以提交到你自己的私有倉庫并且創(chuàng)建好你的Private Pod黔帕,告訴平臺你的倉庫地址即可代咸。至于剩下的事情就交于平臺處理吧,你將會比你完全構(gòu)建一個App花費(fèi)更少的時間成黄。
要實(shí)現(xiàn)插件化是需要建立在組件化的基礎(chǔ)之上的呐芥,這一階段我們只講述關(guān)于組件化開發(fā)相關(guān)的框架及技術(shù),在組件化成型并穩(wěn)定的情況再來考慮插件化開發(fā)奋岁。以下是我們實(shí)現(xiàn)整個框架的腦圖(現(xiàn)階段我們只做圖中右半部分):
驗(yàn)證項(xiàng)目
上述章節(jié)已經(jīng)提到了我們需要做的事以及需要了解的技術(shù)思瘟,以及我們?nèi)绾畏蛛A段實(shí)現(xiàn),這里就不廢話了闻伶,直接開始創(chuàng)建一個驗(yàn)證項(xiàng)目滨攻。
創(chuàng)建私有Repo
-
在Github上創(chuàng)建一個Repository,并且命名為Specs(至于為什么要這樣可以參考組件化開發(fā)之-pod創(chuàng)建規(guī)范)
-
添加Private Pod 并驗(yàn)證
現(xiàn)在我們添加自己私有倉庫就算成功了蓝翰, 接下來就是需要來創(chuàng)建自己的工程光绕。
創(chuàng)建工程
由于這里是驗(yàn)證工程,我們就將工程命名為VerifyProject吧畜份,同樣也需要在Github上創(chuàng)建工程的倉庫(因?yàn)槲覀兒笃谛枰ㄟ^Jenkins自動下載代碼進(jìn)行配置并構(gòu)建)
-
創(chuàng)建項(xiàng)目Repository
將Repository拉取下來并且通過XCode創(chuàng)建工程VerifyProject
-
創(chuàng)建配置文件Config以及Config.swift
???其實(shí)我們可以在后續(xù)通過Jenkins-Pipeline 腳本動態(tài)創(chuàng)建這兩個文件的诞帐,但是這里為什么需要首先創(chuàng)建呢?一個原因是:整項(xiàng)目是由哪些組件構(gòu)建而成是動態(tài)的爆雹,我們需要根據(jù)Web管理后臺的配置來修改配置文件景埃、我們主模塊的顯示以及修改Podfile。還有一個更重要的原因是:我們知道如果你在項(xiàng)目中動態(tài)添加任何文件顶别,XCode是無法將其打包到你的項(xiàng)目中的,因?yàn)槟悴]有指定它這些新創(chuàng)建的文件是需要編譯的拒啰,當(dāng)然也有大神提出了解決方案的使用代碼為 Xcode 工程添加文件驯绎,略微有點(diǎn)麻煩,我們這里是驗(yàn)證工程谋旦,就先跑起來再說剩失,在后階段慢慢完善。
創(chuàng)建完成后册着,你的項(xiàng)目看起來應(yīng)該是這樣的:
-
初始化你的Podfile拴孤,這個時候請你記住不需要在Podfile添加任何依賴
現(xiàn)在你的工程創(chuàng)建也已經(jīng)完成了,現(xiàn)在提交到Github倉庫甲捏,它看起來應(yīng)該是:
創(chuàng)建組件Pod
接下來就是創(chuàng)建你的組件Pod了演熟,在創(chuàng)建組件Pod的時候我建議參考組件化開發(fā)之-pod創(chuàng)建規(guī)范(這僅僅是一個簡單的規(guī)范,適合小項(xiàng)目) 。這里我們創(chuàng)建5個組件模塊稱之為:VerifyA芒粹、VerifyB兄纺、VerifyC、VerifyD化漆、VerifyE估脆,創(chuàng)建方式是相同的,我以VerifyA為例座云。
- 在Github上創(chuàng)建Repository
- 創(chuàng)建Example疙赠,假設(shè)我們采用的是MVVM開發(fā)模式,創(chuàng)建好之后在UIViewcontroller中添加簡單代碼即可朦拖,最后看起來應(yīng)該是:
- 創(chuàng)建.podspec圃阳,并且創(chuàng)建Pod/Classes目錄,將Example的View贞谓、ViewModel限佩、Model拷貝至Classes目錄
$ pod spec create Verify+A
最后你的目錄結(jié)構(gòu)看起來應(yīng)該是:
-
修改.podspec
本地驗(yàn)證.podspec是否正確
$ pod lib lint
- 提交到Github,并遠(yuǎn)程驗(yàn)證裸弦,按照下列步驟需要首先提交Git祟同,然后添加Tag
$ git add .
$ git commit -m "添加Pod"
$ git push
# 添加Tag
$ git tag 0.0.1 # 這里需要與你.podspec中 s.version相同
$ git push --tags
# 驗(yàn)證
$ 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)
業(yè)務(wù)組件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]
- 現(xiàn)在你可以使用了瞧剖,請記住在你的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
- 按照上述方法創(chuàng)建你的其他組件运嗜,最后創(chuàng)建成功之后,在你的Specs中斑鸦,看到的應(yīng)該是這樣
配置Jenkins-Pipeline
在使用Jenkins之前你需要去了解fastlane如何使用窖贤。我的另一篇文章有一個簡單介紹:組件化開發(fā)之-基于Jenkins搭建iOS持續(xù)集成開發(fā)環(huán)境砖顷,但是更多更詳細(xì)功能還請你移步fastlane docs。
-
New Item 創(chuàng)建一個Pipeline
-
配置Pipeline General
-
配置Pipeline Triggers
???我們選擇帶參數(shù)的遠(yuǎn)程觸發(fā)赃梧,從下圖的提示中我們可以看到滤蝠,你只需要訪問JENKINS_URL/job/iOS/job/Verify/build?token=TOKEN_NAME
既可以觸發(fā)了,如果你帶有參數(shù)再添加即可...?token=token&module=A,B,D
-
配置Pipeline
由于在配置Pipeline script時授嘀,我們需要依賴于fastlane物咳,我們這里就先說一說在Pipeline中需要的幾個Stage (這里只以簡單的介紹,其他更多單元測試蹄皱、功能測試等览闰,在后面階段再來詳細(xì)介紹),注意從Jenkins2.5以后Pipeline腳本支持兩種方式巷折,新的一種方式是創(chuàng)建一個Jenkinsfile压鉴,然后再來寫你的腳本,最好的方式是參考官方文檔Pipeline Syntax锻拘,已經(jīng)很詳細(xì)介紹了油吭,在這里我就不細(xì)說了。
# 偽代碼
pipeline {
enviroment {
環(huán)境變量
}
parameters {
參數(shù)配置
}
stages('配置項(xiàng)目') {
stage('拉取原始項(xiàng)目')
stage('寫入配置文件')
stage('配置Podfile')
stage('引入模塊')
stage('構(gòu)建項(xiàng)目')
stage('部署到蒲公英')
}
post {
failure {
hook_failure #通知管理后臺,構(gòu)建失敗上鞠,重新構(gòu)建
}
success {
hook_success # 通知管理后臺际邻,構(gòu)建成功,用戶可以直接去下載
}
}
}
通過fastlane 創(chuàng)建lanes
- 創(chuàng)建你的fastlane
這里需要你進(jìn)入我們之前創(chuàng)建的VerifyProject項(xiàng)目中芍阎,然后初始化fastlane
$ cd VerifyProject
$ fastlane init
如果是第一次使用fastlane init
世曾,你需要按照提示信息輸入你的Apple ID 以及密碼,后面的事情就交給fastlane創(chuàng)建就可以了谴咸。但是有時候你會發(fā)現(xiàn)如果你已經(jīng)使用過了fastlane init
之后轮听,并且這時候如果你的Apple ID的密碼改變了,該怎么辦呢岭佳? fastlane tool chains 提供了一個工具credentials_manager血巍, 這時候你只需要刪除保存的密碼:
$ fastlane fastlane-credentials remove --username xxx@xxx.com
password has been deleted.
現(xiàn)在你可以直接執(zhí)行你的fastlane init
了,如果你想要在執(zhí)行時不需要輸入密碼珊随,你可以:
$ 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 |
+----------------+-----------------------------+
- 創(chuàng)建你的Gemfile述寡,你需要用到fastlane哪些工具集,如我現(xiàn)在的如下:
source 'https://gems.ruby-china.org/'
gem 'fastlane', '2.35.0'
gem 'gym'
gem 'xcov'
gem 'cocoapods', '1.2.1'
gem 'xcpretty'
gem 'dotenv'
- 創(chuàng)建一些環(huán)境配置App.env
# 項(xiàng)目相關(guān)
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叶洞,創(chuàng)建lanes鲫凶,我主要有:
???在創(chuàng)建lane config_generate、config_pod這幾個模塊中我們需要用到shell腳本衩辟,你可以從這里去了解一下基礎(chǔ)的shell腳本寫法:Shell 教程
// 進(jìn)入到fastlane目錄下
$ bundle exec fastlane lanes
--------- ios---------
----- fastlane ios config_generate
生成配置文件
Usage: bundle exec fastlane ios config_generate param:[數(shù)據(jù)/URL等]
----- fastlane ios config_pod
配置Podfile
Usage: bundle exec fastlane ios config_pod
----- fastlane ios build
構(gòu)建項(xiàng)目
Usage: bundle exec fastlane ios build config:[Debug/Release]
----- fastlane ios deploy
部署到蒲公英
Usage: bundle exec fastlane ios deploy config:[Debug/Release]
- 準(zhǔn)備工作已經(jīng)做好螟炫,還記得我們前面提到的Pipeline script是使用偽代碼表示的嗎?現(xiàn)在我們需要來完善它艺晴,以下是我寫的:
pipeline {
agent any // 你也可以使用 agent {label 'mac_for_iOS'}
environment {
BASH_PROFILE = '~/.bashrc'
}
stages {
stage('拉取項(xiàng)目') {
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('構(gòu)建項(xiàng)目') {
steps {
dir('./VerifyProject/fastlane') {
sh 'bundle exec fastlane ios build config:Debug'
}
}
}
stage('部署項(xiàng)目') {
steps {
dir('./VerifyProject/fastlane') {
sh 'bundle exec fastlane ios deploy config:Debug'
}
}
}
}
post {
failure {
echo '構(gòu)建失敗,你可以調(diào)用遠(yuǎn)程通知昼钻,或者發(fā)送一個Email'
}
success {
echo '構(gòu)建成功,你可以調(diào)用遠(yuǎn)程通知,或者發(fā)送一個Email'
}
}
}
-
最后你需要來觸發(fā)你的Pipeline了封寞,由于我們現(xiàn)在是測試然评,沒有與Web端鏈接,但是也能夠模擬遠(yuǎn)程傳遞參數(shù)觸發(fā):
-
最后你想到的應(yīng)該是Build就ok 了對吧狈究?那么你應(yīng)該是想錯了沾瓦,你會看到的是:
各種錯誤,也不要擔(dān)心谦炒,慢慢修改即可,最后你總會看到構(gòu)建成功风喇,我將這個整個的構(gòu)建過程發(fā)布到了Github上了宁改, 你可以從: 業(yè)務(wù)組件B
...
你可以講代碼下載來自己照著做一遍,應(yīng)該就會比較熟悉整個流程魂莫,這里面的代碼還沒有考慮到如何進(jìn)行業(yè)務(wù)組件間的調(diào)用还蹲,我將在下一階段來介紹
** 這里也有一點(diǎn)公有Pod代碼,你也可以來看看:**
最后你會發(fā)現(xiàn):最快熟悉的方式應(yīng)該是自己做一遍,你會發(fā)現(xiàn)里面有很多坑谜喊,踩多了你也就會了潭兽。