iOS自動(dòng)打包平臺(tái)搭建:二 模塊(組件)化開發(fā)

前言

新到公司的時(shí)候發(fā)現(xiàn)公司還在使用傳統(tǒng)的手動(dòng)打包測(cè)試方式,所以利用自己的閑暇時(shí)間開發(fā)了一個(gè) iOS 打包平臺(tái),經(jīng)過不斷改良,現(xiàn)在公司在使用新一款的打包平臺(tái),測(cè)試人員可以輕松完成打包工作。我目前也在重新構(gòu)建平臺(tái),發(fā)布開源版本。

本系列文章記錄完整的 iOS 打包平臺(tái)搭建過程,文章列表記錄如下:

iOS自動(dòng)打包平臺(tái)搭建:一 概述
iOS自動(dòng)打包平臺(tái)搭建:二 模塊(組件)化開發(fā)
iOS自動(dòng)打包平臺(tái)搭建:三 Master/Slave架構(gòu)
iOS自動(dòng)打包平臺(tái)搭建:四 打包腳本(待完成)
iOS自動(dòng)打包平臺(tái)搭建:五 內(nèi)網(wǎng)OTA(待完成)
iOS自動(dòng)打包平臺(tái)搭建:附 安卓打包(待完成)

開端

模塊化?你有沒有搞錯(cuò),為什么在自動(dòng)化打包平臺(tái)搭建的系列文章中亂入這樣一個(gè)話題?額。。。其實(shí)你的懷疑是對(duì)的,的確關(guān)系不大,那為什么要加入這樣一篇文章呢?因?yàn)檫@一系列文章是按照我在開發(fā)自動(dòng)化打包平臺(tái)過程中我認(rèn)為值得說的點(diǎn)去介紹的,模塊的升級(jí)是我的打包平臺(tái)的一個(gè)副產(chǎn)品。我們?cè)谏衔闹姓f到,我們是采用腳本打包,實(shí)際上模塊升級(jí)和打包的差別就在于腳本不同,其他地方是基本相同的。

現(xiàn)在比較流行模塊化方案中一般都是采用 CocoaPods 進(jìn)行管理,也是現(xiàn)在的 iOS 工程中比較常見的方式。我們一般用 CocoaPods 來引入第三方應(yīng)用,但實(shí)際上它的創(chuàng)建私有庫的功能也是很強(qiáng)大的,我們將我們的工程按照功能或者業(yè)務(wù)劃分成N多個(gè)小工程(私有庫),將這些小工程都使用 CocoaPods 管理,譬如 UIView 的 frame 用起來不是很方便,很多人都習(xí)慣為 UIView 添加分類(.top .left .right .bottom 等),對(duì)此可以創(chuàng)建一個(gè)私有庫 XXUIKit,這樣我們就可以在若干工程中引入這個(gè)庫,極大地提高我們的工作效率。然而這看似提高工作效率的事兒卻因?yàn)槲覀儫o法保證所有的同事都能順利使用命令行升級(jí)模塊而失敗。所以一個(gè)簡(jiǎn)單的模塊升級(jí)方式成為這一切實(shí)現(xiàn)的東風(fēng)。

私有庫

概述

一個(gè)私有庫的操作包含如下幾個(gè)步驟:

  • 創(chuàng)建并設(shè)置一個(gè)私有的Spec Repo。
  • 創(chuàng)建Pod的所需要的項(xiàng)目工程文件,并且有可訪問的項(xiàng)目版本控制地址。
  • 創(chuàng)建Pod所對(duì)應(yīng)的podspec文件。
  • 本地測(cè)試配置好的podspec文件是否可用。
  • 向私有的Spec Repo中提交podspec。
  • 在個(gè)人項(xiàng)目中的Podfile中增加剛剛制作的好的Pod并使用。
  • 更新維護(hù)私有庫。

創(chuàng)建私有 Spec Repo

什么是 Spec Repo 呢?它是一個(gè)容器,里面存放 .podspec 或者是 . podspec.json 文件。它實(shí)際上是一個(gè) Git 倉庫 remote 端,當(dāng)你使用 Cocoapods 時(shí),它會(huì)被 clone 到本地 ~/.cocoapods/repos 目錄,我們一般使用的三方庫就是那個(gè) master 的文件夾,它的結(jié)構(gòu)是這樣?jì)饍旱危?/p>

├── REPO NAME[master]
        └── LIB NAME[KWFoundation]
                └── VERSION[0.1.0]
                        └──  LIB NAME.podspec(.json)[KWFoundation.podspec]

既然我們需要搭建一個(gè)私有庫,自然是選擇使用公司內(nèi)部代碼庫或者第三方私有倉庫,這里我選擇我使用我之前創(chuàng)建的私有庫進(jìn)行說明。

首先,創(chuàng)建倉庫,我使用地址如下

https://git.coding.net/kevinM/KWPodSpecs.git

然后在本地執(zhí)行命令,將倉庫與本地進(jìn)行關(guān)聯(lián),命令如下:

# pod repo add [REPO_NAME] [GIT_URL]
pod repo add coding-kevinm-kwpodspecs https://git.coding.net/kevinM/KWPodSpecs.git

我為什么時(shí)候 coding-kevinm-kwpodspecs 這種這么長(zhǎng)的名字呢?因?yàn)閷⑦@個(gè) Spec Repo 中的模塊應(yīng)用到工程后,其他同事在拉取代碼后,執(zhí)行 pod update 時(shí)會(huì)在本地自動(dòng)生成一個(gè)這樣的名字,所以我習(xí)慣這樣命名,那命名的規(guī)則又是怎么樣的呢?我并沒有在官方文檔中查找相關(guān)內(nèi)容,也是自己發(fā)現(xiàn)的規(guī)則,也不知道是否正確,分享一下,url 的主體部分 + 工程擁有者的用戶名 + Repo名字,三部分用 “-” 連接。

如果以上命令執(zhí)行成功的話,應(yīng)該會(huì)在目錄 ~/.cocoapods/repos 下找到 coding-kevinm-kwpodspecs 文件夾,至此創(chuàng)建私有 Spec Repo 創(chuàng)建成功。

創(chuàng)建 Pod 工程

創(chuàng)建 Pod 工程有兩種方式,一種是手動(dòng)創(chuàng)建工程,就像我們平常開發(fā)一樣,另一種是采用 pod 提供的命令,通過模板工程創(chuàng)建。推薦肯定是使用第二種方式,命令如下:


# pod lib create [LIB_NAME]
pod lib create KWFoundation

執(zhí)行以上代碼會(huì)在命令執(zhí)行目錄創(chuàng)建一個(gè)工程,工程的名字是 KWFoundation。至此,一個(gè) Pod 工程就這樣橫空出世,那這個(gè)工程里都有什么呢?其實(shí)它是有一個(gè)模板工程的(模板地址:https://github.com/CocoaPods/pod-template.git),只是創(chuàng)建一個(gè) KWFoundation 的空工程。

我們?cè)陂_發(fā)過程中創(chuàng)建一個(gè)工程是遠(yuǎn)遠(yuǎn)不夠的,而且這個(gè)工程中沒有包含我們需要的基本的代碼,所以我建議創(chuàng)建一個(gè)模塊工程,提交到遠(yuǎn)端倉庫,然后在執(zhí)行以上命令的時(shí)候加上一個(gè)參數(shù) --template-url ,它的作用是指定模塊工程,這樣重寫創(chuàng)建的工程就是一個(gè)和模板工程化一樣的工程了。你是不是又在想怎么創(chuàng)建模塊?建議在官方模塊的基礎(chǔ)上修改,當(dāng)然大神請(qǐng)忽略。

工程結(jié)構(gòu)

代碼上圖中 Classes 文件夾中編寫,這個(gè)大家就都會(huì)了。

然后就是配置 podspec 文件,這個(gè)文件一般我們只需要修改版本、倉庫地址就可以使用了,更詳細(xì)的配置就不在這里展開了,以后有時(shí)間再專用整理一篇文章說明一下。是不是太草率了?附一個(gè)思路給大家,如下圖:

百度搜索

?(??????)哎呦,不錯(cuò)哦~是不是get了一個(gè)新技能 ?6666!

我們可以打開工程隨便寫一些代碼試試(也別太隨便,最起碼是能編譯通過的),然后添加遠(yuǎn)端倉庫,提交代碼到遠(yuǎn)端,并且記得打 tag,如下:

git add .
git commit -m "xxxxxxx"
# 添加遠(yuǎn)端倉庫
git remote add origin https://git.coding.net/kevinM/KWFoundation.git 
#提交到遠(yuǎn)端倉庫
git push origin master     

git tag -m "first release" "0.1.0"
#推送tag到遠(yuǎn)端倉庫
git push --tags

已經(jīng)提交到倉庫了,是不是可以加入到 Repo 了? 騷年,表急!中間還有重要的一步呢,就是在提交前需要驗(yàn)證一下這個(gè)文件是否可用,如果有錯(cuò)誤都是不能添加到 Repo 的,命令如下:

pod lib lint

搞定!。。。等等,what ?有幾個(gè)警告導(dǎo)致失敗了,你是不是在騙我?為什么失敗?

是這樣的,錯(cuò)誤和警告都不被允許的,我上文之所以沒有提到警告是因?yàn)橐话闱闆r下我們都是要添加參數(shù)來忽略警告的, --allow-warnings 就是這個(gè)參數(shù),再來一發(fā)試試。

pod lib lint --allow-warnings

...

-> KWFoundation (0.1.0) 
KWFoundation passed validation.

如果看到 KWFoundation passed validation 字樣,恭喜你騷年,你成功啦!

另外說明兩點(diǎn):

  • 可以使用 --verbose 參數(shù)進(jìn)入啰嗦模式,對(duì)于我們排查錯(cuò)誤還是很有用的
  • 如果其中依賴其他私有庫,使用 --sources 指定 私有庫所在 Repo 地址,多個(gè)使用,分隔

向Spec Repo提交podspec

向 Spec Repo 提交 podspec 需要完成兩點(diǎn),一個(gè)是 podspec 必須通過驗(yàn)證,另一個(gè)就是刪掉無用的注釋(只是為了規(guī)范)。

pod repo push [REPO_NAME] [LIB_NAME].podspec
pod repo push coding-kevinm-kwpodspecs KWFoundation

另外,--allow-warnings、--verbose 同上。

至此,我們的這個(gè)模塊庫就已經(jīng)制作添加完成了,使用pod search命令就可以查到我們自己的庫了。

使用私有庫

和使用 AFNetworking 一樣,在podfile文件中添加如下代碼:

pod 'KWFoundation', '~> 0.1.0'

執(zhí)行 pod update 試一試,是不是出錯(cuò)了?驚不驚喜?意不意外?

哈哈~因?yàn)槲覀兩倭艘徊剑瑢?duì)于私有庫我們必須告訴系統(tǒng)私有庫的 Repo 在哪里,在podfile的最上面加上一行:

# source [REPO_URL]
source "https://git.coding.net/kevinM/KWPodSpecs.git"

更新升級(jí)

所謂更新就是修改代碼,修改tag,然后提交代碼并提交到 Repo,這和創(chuàng)建的時(shí)候幾乎是一樣的,我們很容易發(fā)現(xiàn)命令倒不是很多,但是有些地方要寫很多參數(shù),并且?guī)缀醵际窍嗤?。這也就是為什么我要把模塊升級(jí)作為平臺(tái)的一部分的原因。

綜上,我在開發(fā)平臺(tái)時(shí)整理升級(jí)腳本如下:

#!/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

# 升級(jí)tag

git config user.email "admin@ipack.pub"
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 '版本信息異常(數(shù)據(jù)庫中版本:'$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 '當(dāng)前版本:'${current_tag}',即將升級(jí)到'${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 '檢查代碼出現(xiàn)問題'
  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 '提交到版本庫出現(xiàn)異常'
  exit 1
fi

其中并沒有指定分支,默認(rèn)使用 master 分支。

總結(jié)

本文主要針對(duì)私有庫的搭建、創(chuàng)建工程、集成模塊等進(jìn)行介紹,并且展示打包平臺(tái)模塊升級(jí)腳本以供參考,如發(fā)現(xiàn)錯(cuò)誤或有任何疑問環(huán)境留言交流。

更多內(nèi)容請(qǐng)?jiān)L問 http://blog.makaiwen.com

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容