前言
新到公司的时候发现公司还在使用传统的手动打包测试方式,所以利用自己的闲暇时间开发了一个 iOS 打包平台,经过不断改良,现在公司在使用新一款的打包平台,测试人员可以轻松完成打包工作。我目前也在重新构建平台,发布开源版本。
本系列文章记录完整的 iOS 打包平台搭建过程,文章列表记录如下:
iOS自动打包平台搭建:一 概述
iOS自动打包平台搭建:二 模块(组件)化开发
iOS自动打包平台搭建:三 Master/Slave架构
iOS自动打包平台搭建:四 打包脚本(待完成)
iOS自动打包平台搭建:五 内网OTA(待完成)
iOS自动打包平台搭建:附 安卓打包(待完成)
开端
模块化?你有没有搞错,为什么在自动化打包平台搭建的系列文章中乱入这样一个话题?额。。。其实你的怀疑是对的,的确关系不大,那为什么要加入这样一篇文章呢?因为这一系列文章是按照我在开发自动化打包平台过程中我认为值得说的点去介绍的,模块的升级是我的打包平台的一个副产品。我们在上文中说到,我们是采用脚本打包,实际上模块升级和打包的差别就在于脚本不同,其他地方是基本相同的。
现在比较流行模块化方案中一般都是采用 CocoaPods 进行管理,也是现在的 iOS 工程中比较常见的方式。我们一般用 CocoaPods 来引入第三方应用,但实际上它的创建私有库的功能也是很强大的,我们将我们的工程按照功能或者业务划分成N多个小工程(私有库),将这些小工程都使用 CocoaPods 管理,譬如 UIView 的 frame 用起来不是很方便,很多人都习惯为 UIView 添加分类(.top .left .right .bottom 等),对此可以创建一个私有库 XXUIKit,这样我们就可以在若干工程中引入这个库,极大地提高我们的工作效率。然而这看似提高工作效率的事儿却因为我们无法保证所有的同事都能顺利使用命令行升级模块而失败。所以一个简单的模块升级方式成为这一切实现的东风。
私有库
概述
一个私有库的操作包含如下几个步骤:
- 创建并设置一个私有的Spec Repo。
- 创建Pod的所需要的项目工程文件,并且有可访问的项目版本控制地址。
- 创建Pod所对应的podspec文件。
- 本地测试配置好的podspec文件是否可用。
- 向私有的Spec Repo中提交podspec。
- 在个人项目中的Podfile中增加刚刚制作的好的Pod并使用。
- 更新维护私有库。
创建私有 Spec Repo
什么是 Spec Repo 呢?它是一个容器,里面存放 .podspec 或者是 . podspec.json 文件。它实际上是一个 Git 仓库 remote 端,当你使用 Cocoapods 时,它会被 clone 到本地 ~/.cocoapods/repos 目录,我们一般使用的三方库就是那个 master 的文件夹,它的结构是这样婶儿滴:
├── REPO NAME[master]
└── LIB NAME[KWFoundation]
└── VERSION[0.1.0]
└── LIB NAME.podspec(.json)[KWFoundation.podspec]
既然我们需要搭建一个私有库,自然是选择使用公司内部代码库或者第三方私有仓库,这里我选择我使用我之前创建的私有库进行说明。
首先,创建仓库,我使用地址如下
https://git.coding.net/kevinM/KWPodSpecs.git
然后在本地执行命令,将仓库与本地进行关联,命令如下:
# pod repo add [REPO_NAME] [GIT_URL]
pod repo add coding-kevinm-kwpodspecs https://git.coding.net/kevinM/KWPodSpecs.git
我为什么时候 coding-kevinm-kwpodspecs 这种这么长的名字呢?因为将这个 Spec Repo 中的模块应用到工程后,其他同事在拉取代码后,执行 pod update 时会在本地自动生成一个这样的名字,所以我习惯这样命名,那命名的规则又是怎么样的呢?我并没有在官方文档中查找相关内容,也是自己发现的规则,也不知道是否正确,分享一下,url 的主体部分 + 工程拥有者的用户名 + Repo名字,三部分用 “-” 连接。
如果以上命令执行成功的话,应该会在目录 ~/.cocoapods/repos 下找到 coding-kevinm-kwpodspecs 文件夹,至此创建私有 Spec Repo 创建成功。
创建 Pod 工程
创建 Pod 工程有两种方式,一种是手动创建工程,就像我们平常开发一样,另一种是采用 pod 提供的命令,通过模板工程创建。推荐肯定是使用第二种方式,命令如下:
# pod lib create [LIB_NAME]
pod lib create KWFoundation
执行以上代码会在命令执行目录创建一个工程,工程的名字是 KWFoundation。至此,一个 Pod 工程就这样横空出世,那这个工程里都有什么呢?其实它是有一个模板工程的(模板地址:https://github.com/CocoaPods/pod-template.git),只是创建一个 KWFoundation 的空工程。
我们在开发过程中创建一个工程是远远不够的,而且这个工程中没有包含我们需要的基本的代码,所以我建议创建一个模块工程,提交到远端仓库,然后在执行以上命令的时候加上一个参数 --template-url ,它的作用是指定模块工程,这样重写创建的工程就是一个和模板工程化一样的工程了。你是不是又在想怎么创建模块?建议在官方模块的基础上修改,当然大神请忽略。
代码上图中 Classes 文件夹中编写,这个大家就都会了。
然后就是配置 podspec 文件,这个文件一般我们只需要修改版本、仓库地址就可以使用了,更详细的配置就不在这里展开了,以后有时间再专用整理一篇文章说明一下。是不是太草率了?附一个思路给大家,如下图:
☝(•̀˓◞•́)哎呦,不错哦~是不是get了一个新技能 ?6666!
我们可以打开工程随便写一些代码试试(也别太随便,最起码是能编译通过的),然后添加远端仓库,提交代码到远端,并且记得打 tag,如下:
git add .
git commit -m "xxxxxxx"
# 添加远端仓库
git remote add origin https://git.coding.net/kevinM/KWFoundation.git
#提交到远端仓库
git push origin master
git tag -m "first release" "0.1.0"
#推送tag到远端仓库
git push --tags
已经提交到仓库了,是不是可以加入到 Repo 了? 骚年,表急!中间还有重要的一步呢,就是在提交前需要验证一下这个文件是否可用,如果有错误都是不能添加到 Repo 的,命令如下:
pod lib lint
搞定!。。。等等,what ?有几个警告导致失败了,你是不是在骗我?为什么失败?
是这样的,错误和警告都不被允许的,我上文之所以没有提到警告是因为一般情况下我们都是要添加参数来忽略警告的, --allow-warnings 就是这个参数,再来一发试试。
pod lib lint --allow-warnings
...
-> KWFoundation (0.1.0)
KWFoundation passed validation.
如果看到 KWFoundation passed validation
字样,恭喜你骚年,你成功啦!
另外说明两点:
- 可以使用
--verbose
参数进入啰嗦模式,对于我们排查错误还是很有用的 - 如果其中依赖其他私有库,使用
--sources
指定 私有库所在 Repo 地址,多个使用,
分隔
向Spec Repo提交podspec
向 Spec Repo 提交 podspec 需要完成两点,一个是 podspec 必须通过验证,另一个就是删掉无用的注释(只是为了规范)。
pod repo push [REPO_NAME] [LIB_NAME].podspec
pod repo push coding-kevinm-kwpodspecs KWFoundation
另外,--allow-warnings
、--verbose
同上。
至此,我们的这个模块库就已经制作添加完成了,使用pod search
命令就可以查到我们自己的库了。
使用私有库
和使用 AFNetworking
一样,在podfile
文件中添加如下代码:
pod 'KWFoundation', '~> 0.1.0'
执行 pod update 试一试,是不是出错了?惊不惊喜?意不意外?
哈哈~因为我们少了一步,对于私有库我们必须告诉系统私有库的 Repo 在哪里,在podfile
的最上面加上一行:
# source [REPO_URL]
source "https://git.coding.net/kevinM/KWPodSpecs.git"
更新升级
所谓更新就是修改代码,修改tag,然后提交代码并提交到 Repo,这和创建的时候几乎是一样的,我们很容易发现命令倒不是很多,但是有些地方要写很多参数,并且几乎都是相同的。这也就是为什么我要把模块升级作为平台的一部分的原因。
综上,我在开发平台时整理升级脚本如下:
#!/bin/bash
component_name="KWFoundation"
git_url="https://git.coding.net/kevinM/KWFoundation.git"
version="0.1.1"
repo_name="coding-kevinm-kwpodspecs"
repo_url="https://git.coding.net/kevinM/KWPodSpecs.git"
export LANG=en_US.UTF-8
export LANGUAGE=en_US.UTF-8
export LC_ALL=en_US.UTF-8
CURRENT_USER=`whoami`
USER_DIR=/Users/${CURRENT_USER}
base_path=${USER_DIR}/iPack/iOS/Components
# 拉取代码
# component_path=base_path/${component_name}
if [ ! -d $base_path/${component_name} ];
then
cd $base_path
git clone $git_url
if [ $? != 0 ]
then
echo '拉取代码失败'
exit 1
fi
cd $base_path/${component_name}
else
cd $base_path/${component_name}
git checkout .
if [ $? != 0 ]
then
echo '拉取代码失败'
exit 1
fi
git pull
if [ $? != 0 ]
then
echo '拉取代码失败'
exit 1
fi
fi
# 升级tag
git config user.email "[email protected]"
git config user.name "iPack"
# 获取最后的tag
current_tag=`git describe --tags \`git rev-list --tags --max-count=1\``
# current_tag=$version
if [ $current_tag != $version ]; then
echo '版本信息异常(数据库中版本:'$version',代码库中版本:'$current_tag
exit 1
fi
current_tag_1=`echo $current_tag | cut -d \. -f 1`
current_tag_2=`echo $current_tag | cut -d \. -f 2`
current_tag_3=`echo $current_tag | cut -d \. -f 3`
current_tag_3=$[$current_tag_3+1]
update_tag=${current_tag_1}'.'${current_tag_2}'.'${current_tag_3}
echo '当前版本:'${current_tag}',即将升级到'${update_tag}
file=`find ./ -maxdepth 1 -name "${component_name}*spec*"`
echo '查看到描述文件: '$file
sed -i '' "s/$current_tag/$update_tag/g" "$file"
git add $file
git commit -m "Commit by iPack,update to ${update_tag}"
git push
git tag -m "tag by iPack" ${update_tag}
git push --tags
n_current_tag=`git describe --tags \`git rev-list --tags --max-count=1\``
echo 'ipack-version|'${n_current_tag}
if [ $n_current_tag != $update_tag ]; then
echo ${n_current_tag}'|'
echo ${update_tag}'|'
echo ${n_current_tag} ' not equal to ' ${update_tag}
exit 1
fi
`echo "2.3" > .swift-version`
# 检查问题
/usr/local/bin/pod lib lint --allow-warnings --verbose --sources="${repo_url},https://github.com/CocoaPods/Specs.git"
if [ $? != 0 ]
then
echo '检查代码出现问题'
exit 1
fi
hui=`/usr/local/bin/pod repo list |grep $repo_name`
echo $hui
if [ "$hui" = "" ]; then
/usr/local/bin/pod repo add ${repo_name} ${repo_url}
echo "Finish add ${repo_name} to .cocoapod"
else
echo "Already has ${repo_name} in .cocoapod"
fi
/usr/local/bin/pod repo push ${repo_name} $file --allow-warnings --verbose
if [ $? != 0 ]
then
echo '提交到版本库出现异常'
exit 1
fi
其中并没有指定分支,默认使用 master 分支。
总结
本文主要针对私有库的搭建、创建工程、集成模块等进行介绍,并且展示打包平台模块升级脚本以供参考,如发现错误或有任何疑问环境留言交流。
更多内容请访问 http://blog.makaiwen.com