1:背景
同一套代碼,需要修改app啟動(dòng)圖,圖標(biāo)等資源文件,app名稱(chēng),版本號(hào),bundleID等相應(yīng)的配置,從而來(lái)生成不同的app.如果手動(dòng)去修改的話(huà),費(fèi)時(shí)費(fèi)力不說(shuō),有時(shí)候還有可能會(huì)漏改,改錯(cuò)的情況.所以這里來(lái)介紹使用shell腳本工具,去生成不同配置的app工程.
了解需求之后,可以把需要修改的配置項(xiàng)分為三類(lèi).
分別是1:icon資源文件替換 2:plist文件中字段修改.
2:以下是介紹滿(mǎn)足以上需要的shell腳本
Shell腳本介紹:
Shell腳本并不能作為正式的編程語(yǔ)言,因?yàn)樗窃趌inux的shell中運(yùn)行的,所以成為shell腳本.
shell是一種腳本語(yǔ)言,可以使用邏輯判斷,循環(huán)等語(yǔ)法,可以自定義函數(shù).shell是系統(tǒng)命令的
集合,shell腳本可以實(shí)現(xiàn)自動(dòng)化化運(yùn)維,能大大增加我們的運(yùn)維效率.
操作步驟
首先需要?jiǎng)?chuàng)建shell腳本文件,在終端中輸入touch cp_20.sh,直接創(chuàng)建shell腳本文件(cp_20.sh名字可以自己根據(jù)實(shí)際來(lái)命名)
運(yùn)行腳本時(shí):首先將命令行切換到腳本文件所在的路徑,回車(chē)之后,賦予腳本可執(zhí)行
權(quán)限,需要輸入:chmod +x cp_20.sh,然后輸入sh cp_20.sh就可以直接運(yùn)行腳本了.
Shell腳本開(kāi)頭需要加#!/bin/sh
以#開(kāi)頭的行作為解釋說(shuō)明,腳本以.sh結(jié)尾,用于區(qū)分這是一個(gè)shell腳本
在每個(gè)腳本的開(kāi)頭都使用”#!”,這意味著告訴你的系統(tǒng)這個(gè)文件的執(zhí)行需要指定一個(gè)
解釋器.“#!”實(shí)際上是一個(gè)2 字節(jié)的魔法數(shù)字,這是指定一個(gè)文件類(lèi)型的特殊標(biāo)記, 換句
話(huà)說(shuō), 在這種情況下,指的就是一個(gè)可執(zhí)行的腳本(鍵入man magic 來(lái)獲得關(guān)于這個(gè)迷人話(huà)題的
更多詳細(xì)信息).在#!之后接著是一個(gè)路徑名.這個(gè)路徑名指定了一個(gè)解釋腳本中命令的程序,這
個(gè)程序可以是 shell,程序語(yǔ)言或者是任意一個(gè)通用程序.這個(gè)指定的程序從頭開(kāi)始解釋并且執(zhí)
行腳本中的命令(從#!行下邊的一行開(kāi)始),忽略注釋上邊每一個(gè)腳本頭的行都指定了一個(gè)不同
的命令解釋器,如果是/bin/sh,那么就是默認(rèn)shell(在Linux 系統(tǒng)中默認(rèn)是bash.當(dāng)然”#!”也可以被
忽略,不過(guò)這樣你的腳本文件就只能是一些命令的集合,不能夠使用shell 內(nèi)建的指令了,如果不
能使用變量的話(huà),當(dāng)然這也就失去了腳本編程的意義了.
腳本說(shuō)明
appInfosLength=${#appBundleInfos[*]}
獲取數(shù)組個(gè)數(shù)其他寫(xiě)法 =${#appBundleInfos[@]}
bedinTime=`date +%s` 記錄開(kāi)始時(shí)間,結(jié)尾有結(jié)束時(shí)間,用來(lái)計(jì)時(shí)打出來(lái)一個(gè)包需要多長(zhǎng)時(shí)間
mkdir ${ipaPath}/allChannelIpa創(chuàng)建打包目錄 還可以加雙引號(hào)寫(xiě):mkdir “${ipaPath}/allChannelIpa”
改路徑的意思是在打包素材文件中再創(chuàng)建一個(gè)allChannelIpa文件來(lái)裝打好的ipa包
allIPAPackPath="${ipaPath}/allChannelIpa”聲明allIPAPackPath方便一下直接獲取ipa路徑
xcodebuild archive -workspace ${projectDir}/${schemeName}.xcworkspace-scheme ${schemeName} -configuration Release -sdkiphoneosclean?-archivePath ${allIPAPackPath}/${schemeName}.xcarchive? Build生成APP
-workspace 項(xiàng)目路徑下面的.xcworkspace
–scheme 項(xiàng)目名稱(chēng)
-configuration ?配置打包的環(huán)境Release或者debug
-archivePath archive 的路徑
if [[$? = 0 ]]; then ([[$? = 0]] 等同于[”$?” != “0”] )
echo "\033[31m 編譯成功\n \033[0m"
else echo "\033[31m
編譯失敗\n \033[0m"
fi???利用if語(yǔ)句判斷build是否成功,成功的話(huà)就輸出編譯成功 echo輸出打印
echo
"\033[31m 編譯成功\n
\033[0m"
30--37前景色
40-----47 背景色
\033[0m恢復(fù)默認(rèn)顏色屬性
\033[45;36m設(shè)置背景為45前景為36
"\033[y;xH \033[10;25h" 把光標(biāo)置于10行25列處
\033[K 清除光標(biāo)行的內(nèi)容
\033[u 恢復(fù)光標(biāo)位
\033[s 保存當(dāng)前光標(biāo)位
//所有顏色和修飾符https://misc.flogisoft.com/bash/tip_colors_and_formatting
//與文件存在與否的判斷-e是否存在
#
----全部打包----開(kāi)始使用for遍歷數(shù)組
for((i=0;i<appInfosLength;i++)); do
Bundle Name (CFBundleName)
appName=${appNameInfos[${i}]}
appDisplayName=${appNameInfos[${i}]}
appIconName=${appIconInfos[${i}]}
appBundleId=${appBundleInfos[${i}]}
mkdir $allIPAPackPath/${appName}創(chuàng)建不同app
ipa目錄(可創(chuàng)建可不創(chuàng)建)
Applications_Path=${allIPAPackPath}/${schemeName}.xcarchive/Products/Applications #將對(duì)應(yīng)的 icon
復(fù)制到需要修改的 app的目錄下.xcarchive 文件下對(duì)應(yīng)的Applications文件路徑
rm -rf $Applications_Path/${projectName}.app/icon.png
#先刪除項(xiàng)目中原有的icon,不然直接copy的話(huà),會(huì)有icon重用的現(xiàn)象
cp -Rf $iconPath/${appIconName}/icon.png $Applications_Path/${projectName}.app/icon.png
#使用mac自帶的plistbuddy修改plist文件
plist_path=$Applications_Path/${schemeName}.app/info.plist
/usr/libexec/PlistBuddy-c "Set :CFBundleName? $appName"
$plist_path
/usr/libexec/PlistBuddy-c "Set :CFBundleDisplayName? $appDisplayName" $plist_path
/usr/libexec/PlistBuddy-c "Set :CFBundleIdentifier? $appBundleId"
$plist_path
/usr/libexec/PlistBuddy
-c "set CFBundleURLTypes:0:CFBundleURLSchemes:0 ch$appBundleId" ${plist_path}
Mac自帶的一個(gè)操作plist文件的工具
路徑:/usr/libexec/PlistBuddy
使用: /usr/libexec/PlistBuddy -c "Set key value" plistUrl
# 生成 ipa
xcodebuild -exportArchive -exportOptionsPlist "$allIPAPackPath/ExportOptions.plist”
?-archivePath ${allIPAPackPath}/${schemeName}.xcarchive
?-exportPath $allIPAPackPath/${appName}/$appBundleId
#移動(dòng)位置重命名
mv /$allIPAPackPath/${appName}/$appBundleId/Rainbow.ipa /$allIPAPackPath/${appName}/$appBundleId.ipa
# 每打出來(lái)一個(gè)ipa包都得重簽名,不然app安裝不上 這里使用heyu證書(shū)
codesign -f -s "Apple Development: xxxx"? --entitlements"$allIPAPackPath/ExportOptions.plist" $allIPAPackPath/${appName}/$appBundleId.ipa
# 清除無(wú)關(guān)文件
rm -r $allIPAPackPath/${appName}/$appBundleId
# 結(jié)束時(shí)間
endTime=`date +%s`
echo
-e "打包時(shí)間$[endTime - beginTime ]秒"
輸出打包時(shí)間,從而可以更明顯的看出打一個(gè)包需要多長(zhǎng)時(shí)間
done 結(jié)束打包進(jìn)程
知識(shí)延伸
1 :
-f是否為普通文件
-d 是否為目錄
-s 是否為非空的文件
-p 是否為管道文件
-b 是否為塊設(shè)備文件
-c 是否為字符設(shè)備文件
2: 條件分支分三種條件:單分支,雙分支,多分支
單分支:
if[];then
echo
'aa'
fi
雙分支:
if[];then
echo
'aa'
else
echo
'bb'
多分支:
if[];then
echo
'aa'
elif
echo
'bb'
elif
echo
'cc'
fi
3:
$var 引用var變量的值
${var} 引用var變量的值
${var%a*} 引用var變量的值并且截取a左邊的字符串顯示,如果字符串有多個(gè)a碉输,則按從左向右最后一個(gè)a截取
${var%%a*} 引用var變量的值并且截取a左邊的字符串顯示驾茴,如果字符串有多個(gè)a,則按從左向右第一個(gè)a截取
${var#*a} 引用var變量的值并且截取a右邊的字符串顯示侥加,如果字符串有多個(gè)a,則按從左向右第一個(gè)a截取
${var##*a} 引用var變量的值并且截取a右邊的字符串顯示,如果字符串有多個(gè)a静尼,則按從左向右最后一個(gè)a截取
${var:3} 引用var變量的值并且從第3個(gè)字符開(kāi)始截取
${var:3:6} 引用var變量的值并且從第3個(gè)字符開(kāi)始截取,截取6個(gè)字符顯示
${#var} 返回var變量值的長(zhǎng)度
${var/a/b} 替換變量值的字符串传泊,這里是把var變量值里的a換成b,如果有多個(gè)a也只能換一次
${var//a/b} 替換變量值的字符串鼠渺,這里把var變量值里的a全換成b
4: 循環(huán)語(yǔ)句:
分為三種:while do循環(huán),until do循環(huán),for循環(huán)
while do循環(huán)i=10
while
[ $i
-eq
5 ];do
echo
$i;
((i--));
[ $i
-eq
5 ]可以換成(($i==5))這樣寫(xiě)
until do循環(huán):知道xx才執(zhí)行
i=10
until (($a<0));do
echo $i;
((i--));
done;
for循環(huán)
for((i=1;i<=10;i++));do
echo $i
done;
5: PlistBuddy的幾個(gè)關(guān)鍵點(diǎn):
如何定義嵌套的鍵: 每個(gè)鍵之間使用":"符號(hào)分隔
如果鍵值的名稱(chēng)包含空格等特殊字符的時(shí)候,如同命令行的轉(zhuǎn)義字符一樣眷细,使用"/"來(lái)轉(zhuǎn)義拦盹,比如:
":Software:Gallery:Online/ Marketplace".
PlistBuddy如果不使用"-c"參數(shù),則進(jìn)入人機(jī)交互模式, "-c"的意思就是執(zhí)行它后面的命令列表溪椎,而命令如果有參數(shù)普舆,需要把它們包含在引號(hào)中恬口。
需要注意的是scheme的修改:scheme
的數(shù)據(jù)結(jié)構(gòu)為 數(shù)組元素可能是字典,字典key對(duì)應(yīng)的value可能是數(shù)組沼侣,因此需要事先知道要修改的值的數(shù)據(jù)結(jié)構(gòu)和位置祖能,在使用plist工具時(shí)指定字典對(duì)應(yīng)的key /usr/libexec/PlistBuddy
-c "set CFBundleURLTypes:0:CFBundleURLSchemes:0 ch$appBundleId" ${plist_path}
該意思是取?CFBundleURLTypes?數(shù)組下的第一個(gè)元素 X,再取
X 下?CFBundleURLSchemes?數(shù)組下的第一個(gè)元素 Y蛾洛,并更新Y的值為chappBundleId.