Jenkins十一:一份代碼多個(gè)APP的多Target和單Target比較

前一篇:Jenkins十:Mac通過(guò) Tomcat里安裝Jenkins配置Master-Slave打包iOS并上傳到svn服務(wù)器
后一篇:Jenkins十二:Jenkins忘記賬號(hào)密碼處理

前言

隨著項(xiàng)目的發(fā)展蝇恶,一般的項(xiàng)目都遇到一份代碼可能會(huì)要做出多個(gè)APP的情況撮弧,
典型的就是電商的普通用戶版商家版,一些換膚游戲的多個(gè)馬甲APP耀盗。這兩個(gè)版本大部分UI及邏輯都是一樣的卦尊,只會(huì)在小部分頁(yè)面主題顏色及業(yè)務(wù)有些許差別

一、單target忿薇,代碼里寫死
在代碼里寫死躏哩,用多個(gè)If else,switch來(lái)進(jìn)行判斷,使用不同的主題及圖片筋栋,以及區(qū)分不同版本的業(yè)務(wù)(這種版本方便簡(jiǎn)潔正驻,誰(shuí)都會(huì),但是不方便擴(kuò)展襟交,以及容易出現(xiàn)bug伤靠,處理起來(lái)也很low)

二、多Target
焕梅,這種情況就適合用多Target-Scheme的方式管理,圖片等資源每個(gè)target自個(gè)一分徒欣,相同的代碼一起引入蜗字,不同部分添加到不同的平臺(tái)(這個(gè)各個(gè)不同的平臺(tái)的圖片及資源都獨(dú)立隔離,不同的平臺(tái)又可以共用一些相同的代碼及資源粗梭,做到了既公用又獨(dú)立级零,壞處是如果平臺(tái)或馬甲包超過(guò)3個(gè)甚至更多時(shí)及其難管理,沒(méi)次新創(chuàng)建的文件都有可能這個(gè)target引入了那個(gè)target又沒(méi)引入鉴嗤,而且如果一直在持續(xù)不斷的增加新的馬甲包平臺(tái)時(shí)序调,創(chuàng)建target也是一件痛苦的事)

三、單Target,不同的平臺(tái)包在打包時(shí)動(dòng)態(tài)配置
一個(gè)target硬耍,在業(yè)務(wù)開(kāi)發(fā)時(shí)不同平臺(tái)一些差異化的地方都抽取出來(lái)做成plist進(jìn)行配置化边酒,在打包時(shí)手動(dòng)或自動(dòng)的修改bundleId、發(fā)布證書坯认、描述文件及其他配置資源和文件(這種方式集合了方式一氓涣、方式二的優(yōu)點(diǎn)春哨,就是不同的平臺(tái)進(jìn)行了有效隔離,適合隨時(shí)增加新的平臺(tái)赴背,但也集合了方案一、方案二的缺點(diǎn)燃观,同時(shí)如果要每次手動(dòng)在xcode修改配置時(shí)是是否痛苦的,必須要和Jenkins配合自動(dòng)打包才能達(dá)到最佳功效)

將pbxpro轉(zhuǎn)換成xml命令
plutil -convert xml1 -r -o test.xml project.pbxproj
plutil -convert json -r -o test.json Lottery.xcodeproj/project.pbxproj

通過(guò)腳本讀取p12配置并修改project配置進(jìn)行自動(dòng)化修改打包
1番川、先從svn或網(wǎng)絡(luò)或其他地方下載描述文件xxxx.mobileprovision

svn_name="xxx"
svn_pwd="xxx"
certificate_folder="./certificate"
svn export "https://xxx.xx.xx.xx/svn/xxx/xxx.mobileprovision" \
"./xxx.mobileprovision" \
--username ${svn_name} \
--password ${svn_pwd} \
--force

2颁督、解析描述文件

#設(shè)置跨shell環(huán)境及設(shè)置好賬號(hào)密碼
tempVarFile="./tempVarFile.txt"
#2.2浇雹、讀取描述文件
security cms -D -i "./xxx.mobileprovision" > "./profile.plist"
#2.3 讀取信息
#證書持有者機(jī)構(gòu)
config_TeamName=$(/usr/libexec/PlistBuddy -c "print TeamName" "./profile.plist")
echo "config_TeamName='${config_TeamName}'" >> $tempVarFile
#證書持有者組Id
config_teamId=$(/usr/libexec/PlistBuddy -c "print :Entitlements:com.apple.developer.team-identifier" "./profile.plist")
echo "config_teamId='${config_teamId}'" >> $tempVarFile
#bundleId
config_identifier=$(/usr/libexec/PlistBuddy -c "print :Entitlements:application-identifier" "./profile.plist")
config_identifier_cut="${config_teamId}."
config_identifier=${config_identifier#*$config_identifier_cut}
echo "config_identifier='${config_identifier}'" >> $tempVarFile
#發(fā)布證書名稱
config_disName=$(/usr/libexec/PlistBuddy -c "print Name" "./profile.plist")
echo "config_disName='${config_disName}'" >> $tempVarFile
#描述文件UUID
config_uuid=$(/usr/libexec/PlistBuddy -c "print UUID" "./profile.plist")
echo "config_uuid='${config_uuid}'" >> $tempVarFile
#過(guò)期時(shí)間
config_expirationDate=$(/usr/libexec/PlistBuddy -c "print ExpirationDate" "./profile.plist")
echo "config_expirationDate='${config_expirationDate}'" >> $tempVarFile

cat $tempVarFile
source $tempVarFile

3昭灵、修改project配置文件

APP_NAME="xxxx"
cp "./${APP_NAME}.xcodeproj/project.pbxproj" backup.project.pbxproj
# 轉(zhuǎn)換成plist文件
plutil -convert xml1 backup.project.pbxproj
#重命名成plist
cp backup.project.pbxproj backup.project.plist
pbx_rootObject=$(/usr/libexec/PlistBuddy -c "print :rootObject" "./backup.project.plist")
pbx_target=$(/usr/libexec/PlistBuddy -c "print :objects:$pbx_rootObject:targets:0" "./backup.project.plist")
target_buildConfigurationList=$(/usr/libexec/PlistBuddy -c "print :objects:$pbx_target:buildConfigurationList" "./backup.project.plist")
target_debug=$(/usr/libexec/PlistBuddy -c "print :objects:$target_buildConfigurationList:buildConfigurations:0" "./backup.project.plist")
target_release=$(/usr/libexec/PlistBuddy -c "print :objects:$target_buildConfigurationList:buildConfigurations:1" "./backup.project.plist")


#2.3.1烂完、生成change.json文件
cat > "./config_change.json" << END_TEXT
{
  "insert" : {

  },
  "remove" : {
  },
  "modify" : {
    "objects.$target_debug.buildSettings.PRODUCT_BUNDLE_IDENTIFIER" : "${config_identifier}",
    "objects.$target_release.buildSettings.PRODUCT_BUNDLE_IDENTIFIER" : "${config_identifier}",
    "objects.$target_debug.buildSettings.PROVISIONING_PROFILE_SPECIFIER":"${config_disName}",
    "objects.$target_release.buildSettings.PROVISIONING_PROFILE_SPECIFIER":"${config_disName}",
    "objects.$target_release.buildSettings.DEVELOPMENT_TEAM":"${config_teamId}",
    "objects.$target_debug.buildSettings.DEVELOPMENT_TEAM":"${config_teamId}",
    "objects.$pbx_rootObject.attributes.TargetAttributes.$pbx_target.DevelopmentTeam":"${config_teamId}",
    "objects.$pbx_rootObject.attributes.TargetAttributes.$pbx_target.ProvisioningStyle":"Manual",
    "objects.$target_debug.buildSettings.CODE_SIGN_STYLE":"Manual",
    "objects.$target_release.buildSettings.CODE_SIGN_STYLE":"Manual",
    "objects.$target_release.buildSettings.CODE_SIGN_IDENTITY":"iPhone Distribution",
    "objects.$target_debug.buildSettings.CODE_SIGN_IDENTITY":"iPhone Distribution",
    
  }
}
END_TEXT
cat "./config_change.json"

#判斷是否存在pbxproj
if [ ! -x "/usr/local/bin/pbxproj" ];then
echo "---------不存在pbxproj----------"
#下載命令行工具pbxproj
curl -o pbxproj "https://github.com/yulingtianxia/pbxprojHelper/releases/download/1.2.1/pbxproj"
#移動(dòng)到bin下
mv "./pbxproj" "/usr/local/bin/pbxproj"
#設(shè)置權(quán)限
chmod 755 "/usr/local/bin/pbxproj"
else
    echo "---------已經(jīng)存在pbxproj---------"
fi
#2.3.2抠蚣、修改配置
/usr/local/bin/pbxproj -apply "./config_change.json" "./${APP_NAME}.xcodeproj"


#2.4、修改展示名稱
/usr/libexec/PlistBuddy -c "Set :CFBundleDisplayName ${config_displayName}" "./Resource/platforms/OneNumberDev-Info.plist"

#2.5缓屠、修改版本號(hào)等信息


#2.6护侮、生成由xxx.xcarchive導(dǎo)出xxx.ipa的ExportOptions.plist
cat > "./ExportOptions.plist" << END_TEXT
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>compileBitcode</key>
    <true/>
    <key>destination</key>
    <string>export</string>
    <key>method</key>
    <string>enterprise</string>
    <key>provisioningProfiles</key>
    <dict>
        <key>${config_identifier}</key>
        <string>${config_disName}</string>
    </dict>
    <key>signingCertificate</key>
    <string>iPhone Distribution</string>
    <key>signingStyle</key>
    <string>manual</string>
    <key>stripSwiftSymbols</key>
    <true/>
    <key>teamID</key>
    <string>${config_teamId}</string>
    <key>thinning</key>
    <string>&lt;none&gt;</string>
</dict>
</plist>
END_TEXT



echo "===========修改好配置文件了===================="

4羊初、檢測(cè)和安裝證書

#電腦賬號(hào)
Node_User="xxx"
#登錄密碼
Node_Pwd="xxx"
#查找安裝過(guò)的證書
security find-identity -v \
codesigning "/Users/$Node_User/Library/Keychains/login.keychain" \
> "./loginKeychain.txt"


#解鎖鑰匙串
security unlock-keychain -p ${Node_Pwd} "/Users/${Node_User}/Library/Keychains/login.keychain"

# 檢測(cè)p12是否存在
function existP12()
{
    find_txt=$*
    replace_txt="$(date +%Y%m%d-%H%M%S)"
    findPath="./loginKeychain.txt"
    sed -i -e "s|$find_txt|'$replace_txt'|" $findPath
    if grep -rn -s -q $replace_txt $findPath; then
      return 1
    else
      return 0
    fi
}
#檢測(cè)是否已安裝了發(fā)布證書
dis_exist_name="iPhone Distribution: $config_TeamName"
existP12 $dis_exist_name
if $? == 0 ; then
    echo "=====沒(méi)有發(fā)布證書======"
    dis_file_path="${certificate_folder}/${config_disp12_name}"
    security import $dis_file_path \
    -k "/Users/${Node_User}/Library/Keychains/login.keychain" \
    -P "$config_disp12_pwd" \
    -T "/usr/bin/codesign"
else
    echo "=====已經(jīng)存在發(fā)布證書====="
fi

#檢測(cè)是否已安裝了推送證書
#aps_exist_name="Apple Development IOS Push Services: $config_identifier"
#existP12 $aps_exist_name
#if $? == 0 ; then
#   echo "=====沒(méi)有發(fā)布推送證書====="
#    aps_file_path="${certificate_folder}/${config_apsp12_name}"
#   security import $aps_file_path \
#   -k "/Users/${Node_User}/Library/Keychains/login.keychain" \
#   -P "$config_apsp12_pwd" \
#   -T "/usr/bin/codesign"
#else
#   echo "=====已經(jīng)存在發(fā)布推送證書====="
#fi

#判斷有沒(méi)有描述證書
mobileprovision_path="/Users/$Node_User/Library/MobileDevice/Provisioning Profiles/$config_uuid.mobileprovision"

cp ${certificate_folder}/${config_profileFile} "./$config_uuid.mobileprovision"
mv -f "./$config_uuid.mobileprovision" "${mobileprovision_path}"

正式打包

#!/bin/bash

#臨時(shí)變量
source "./tempVarFile.txt"

# 平臺(tái)及SVN文件夾名稱
APP_NAME="xxx"
SCHEMECA="xxx"
#打包日期(年月日)
DATEOFDAY="$(date +%Y%m%d)"
#打包的時(shí)間(年月日-時(shí)分秒)
DATE="$(date +%Y%m%d-%H%M%S)"
source "./tempVarFile.txt"
#設(shè)置好svn環(huán)境,防止中文亂七八糟的問(wèn)題
export LC_ALL=en_US.UTF-8 
export LANG=en_US.UTF-8 
export LANGUAGE=en_US.UTF-8 


#*************************************
#下面2行是集成有Cocopods的用法
security unlock-keychain -p ${Node_Pwd} /Users/${Node_User}/Library/Keychains/login.keychain
echo "=================clean================="
echo xcodebuild -workspace "./${APP_NAME}.xcworkspace" -scheme ${SCHEMECA}  -configuration 'Release' clean
xcodebuild -workspace "./${APP_NAME}.xcworkspace" -scheme ${SCHEMECA}  -configuration 'Release' clean

echo "+++++++++++++++++archive+++++++++++++++++"
#生成的archive的位置
ArchivePath="./${SCHEMECA}_${DATE}.xcarchive"

xcodebuild archive \
-workspace "./${APP_NAME}.xcworkspace" \
-scheme ${SCHEMECA} \
-configuration Release \
-archivePath ${ArchivePath}

echo "+++++++++++++++++export ipa+++++++++++++++++"
APPPath="${ArchivePath}/Products/Applications/${SCHEMECA}.app"
IPAFolderPath="./${SCHEMECA}_${DATE}"
IPAPath="${WORKSPACE}/${SCHEMECA}_${DATE}.ipa"

#在上一個(gè)shell里生成的文件
myOptionsPlist="./ExportOptions.plist"


#生成xxx.ipa
echo xcodebuild -exportArchive \
-archivePath "${ArchivePath}" \
-exportPath "${IPAFolderPath}" \
-exportOptionsPlist ${myOptionsPlist}
xcodebuild -exportArchive \
-archivePath "${ArchivePath}" \
-exportPath "${IPAFolderPath}" \
-exportOptionsPlist ${myOptionsPlist}

##讀取打包后的內(nèi)容的Info
InfoPath="${APPPath}/Info.plist"
#取build值
bundleVersion=$(/usr/libexec/PlistBuddy -c "print CFBundleShortVersionString" "${InfoPath}")
#取APP名稱

#打包代碼的分支
tagOrBranchName=${GIT_BRANCH_TAG/origin\//""}
#生成的唯一名稱
UNIQUE_NAME="${APP_NAME}_${SCHEMECA}_V${bundleVersion}_${tagOrBranchName}_${DATE}"
IPANAME="${UNIQUE_NAME}.ipa"
ParentSVNPath="./svn_${DATE}"
local_svn_Path="${ParentSVNPath}/${svn_ipa_folder}/${DATEOFDAY}"
#如果沒(méi)有文件夾,則創(chuàng)建文件夾
if [ ! -d ${local_svn_Path}  ];then
  mkdir -p ${local_svn_Path}
fi
echo cp "${IPAFolderPath}/${SCHEMECA}.ipa" "${local_svn_Path}/${IPANAME}"
cp "${IPAFolderPath}/${SCHEMECA}.ipa" "${local_svn_Path}/${IPANAME}"
#生成dSYM
dsymutil ${APPPath}/${SCHEMECA} -o "${local_svn_Path}/${UNIQUE_NAME}.app.dSYM"


echo "+++++++++++++++++將ipa上傳到svn+++++++++++++++++"
svn import "${local_svn_Path}/${IPANAME}" \
"https://xxx/xxx/${svn_ipa_folder}/${DATEOFDAY}/${IPANAME}" \
--username ${svn_name} \
--password ${svn_pwd} \
-m "測(cè)試添加文件"

echo "+++++++++++++++++將dsYM上傳到svn+++++++++++++++++"
svn import "${local_svn_Path}/${UNIQUE_NAME}.app.dSYM" \
"https://xxx/xxx/${svn_ipa_folder}/${DATEOFDAY}/${UNIQUE_NAME}.app.dSYM" \
--username ${svn_name} \
--password ${svn_pwd} \
-m "測(cè)試添加文件"

if [ ! -f "${local_svn_Path}/${IPANAME}" ];then 
    echo ">>>>>不存在ipa>>>>>>>"
    cd ..
    rm -rf "./$JOB_NAME"
    exit 1
fi
if [ ! -d "${local_svn_Path}/${UNIQUE_NAME}.app.dSYM" ]; then 
    echo ">>>>>不存在dsYM>>>>>>>"
    cd ..
    rm -rf "./$JOB_NAME"
    exit 1
fi

cd ..
echo $JOB_NAME
rm -rf "./$JOB_NAME"
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市贩据,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌饱亮,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,843評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件剔宪,死亡現(xiàn)場(chǎng)離奇詭異壹无,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)哈街,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,538評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門骚秦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)璧微,“玉大人,你說(shuō)我怎么就攤上這事前硫。” “怎么了阶剑?”我有些...
    開(kāi)封第一講書人閱讀 163,187評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵危号,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我猪半,道長(zhǎng)偷线,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 58,264評(píng)論 1 292
  • 正文 為了忘掉前任乏奥,我火速辦了婚禮亥曹,結(jié)果婚禮上盏檐,老公的妹妹穿的比我還像新娘驶悟。我一直安慰自己,他們只是感情好硫豆,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,289評(píng)論 6 390
  • 文/花漫 我一把揭開(kāi)白布笼呆。 她就那樣靜靜地躺著,像睡著了一般汗茄。 火紅的嫁衣襯著肌膚如雪铭若。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,231評(píng)論 1 299
  • 那天瞳腌,我揣著相機(jī)與錄音镜雨,去河邊找鬼。 笑死荚坞,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的各淀。 我是一名探鬼主播瞭空,決...
    沈念sama閱讀 40,116評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼咆畏,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼吴裤!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起麦牺,我...
    開(kāi)封第一講書人閱讀 38,945評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎魏颓,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體沦童,經(jīng)...
    沈念sama閱讀 45,367評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡叹话,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,581評(píng)論 2 333
  • 正文 我和宋清朗相戀三年驼壶,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片热凹。...
    茶點(diǎn)故事閱讀 39,754評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡般妙,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出股冗,到底是詐尸還是另有隱情,我是刑警寧澤烹棉,帶...
    沈念sama閱讀 35,458評(píng)論 5 344
  • 正文 年R本政府宣布怯疤,位于F島的核電站,受9級(jí)特大地震影響伏社,放射性物質(zhì)發(fā)生泄漏塔淤。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,068評(píng)論 3 327
  • 文/蒙蒙 一聪黎、第九天 我趴在偏房一處隱蔽的房頂上張望备恤。 院中可真熱鬧锦秒,春花似錦喉镰、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,692評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至偿凭,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間痰哨,已是汗流浹背匾嘱。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,842評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留撬讽,地道東北人悬垃。 一個(gè)月前我還...
    沈念sama閱讀 47,797評(píng)論 2 369
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像烘豌,于是被迫代替她去往敵國(guó)和親看彼。 傳聞我的和親對(duì)象是個(gè)殘疾皇子廊佩,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,654評(píng)論 2 354