原创 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代码,你也可以来看看:**
最后你会发现:最快熟悉的方式应该是自己做一遍,你会发现里面有很多坑,踩多了你也就会了。