内容简介:项目每次更新要打十几个包,广发说传承下来的自动打包脚本突然不好使了,现在每次打包上传都要弄到凌晨,以后改名叫稀发好了。看着他越来越秃的头,我这父爱就藏匿不住,必须要帮他分担(当然是被逼的)。这个项目十几个包,不同图标、App名字,手动打包不但慢,而且重复枯燥的工作出错概率也指数上升。所以如果你的项目也要打几个包的话,花时间学习自动打包还是值得的。如果只用打一个包,虽然自动打包时间会快点,但学习成本还是在那,见仁见智了。重点是,利用重签名修改自定义的图片、App名字等,不用重复编译,能极大缩短打包时间。
项目每次更新要打十几个包,广发说传承下来的自动打包脚本突然不好使了,现在每次打包上传都要弄到凌晨,以后改名叫稀发好了。看着他越来越秃的头,我这父爱就藏匿不住,必须要帮他分担(当然是被逼的)。
这个项目十几个包,不同图标、App名字,手动打包不但慢,而且重复枯燥的工作出错概率也指数上升。所以如果你的项目也要打几个包的话,花时间学习自动打包还是值得的。如果只用打一个包,虽然自动打包时间会快点,但学习成本还是在那,见仁见智了。
重点是,利用重签名修改自定义的图片、App名字等,不用重复编译,能极大缩短打包时间。
证书知识
网上关于证书配置不乏好文章,一搜一大堆,但大多都没有介绍分别有什么用。
- CSR:Certificate Singing Request,证书签名请求文件。
包含 电脑的信息 。所以创建时不需要填任何和发布等有关的信息。
- Certificates证书:发布者证书。Apple Develop的ID 对某部电脑的授权证书。
电脑拥有这个证书后,有权对该Apple Developer的ID下所有App进行真机测试、打包、发布。注意这里,并未指定App,换句话说,和App无关。
包含电脑的信息和Apple Developer的信息。
- CSR和Certificates的联系
上面提到了Certificates包含了电脑的信息,这个信息来自于CSR。所以在创建Certificates时,需要提交CSR。
- Certificates导出p12文件
上面提到,拥有此证书才有权做那些事。如果另一部电脑想发布,也需要证书。如果又创建一个新证书也能解决,但一般一个开发者帐号创建一个发布证书就够了,而且苹果对这证书数量有限制。这时候导出p12文件,相当于拷贝了一份证书(不占苹果限制数量)。给另一部电脑安装后,另一部电脑就有权了。
到这里,笔者就迷惑了CSR包含了电脑的信息,然后又能拷贝给其他电脑用,有什么用呢。希望大佬能解惑。
上面提到的与App无直接关系,以下才与App建立起联系。
- App IDs
在该Apple Developer下注册App。这里要填Name和Bundle ID。这里的Bundle ID将在Xcode中匹配证书。
之前听李大神说,新建一个新项目,然后改为公司项目中的Bundle ID,App也能真机测试,就是因为通过Bundle ID来匹配。
- Provisioning Profiles:PP文件。.mobileprovision后缀。
包含appID,开发者证书。
创建时,开发版和发布版有区别。前者要选设备,后者不用。
创建下载后,Xcode就会自动匹配,当然也可以手动匹配。
- 做项目时,如果不是你负责的,别人通常会发你.p12和.mobileprovision文件。前者授权你的电脑Apple Developer的ID权限,后者授权App权限。
自动打包
本文采用的是xcodebuild。
说起自动打包就脑壳疼。一直对命令行有恐惧,只能一步一步来了。先了解命令行命令,然后新建一个项目熟悉一下。
xcodebuild 简介
xcodebuild 是xcode提供的打包项目或者工程的命令。
输入 man xcodebuild 可以查看文档。
这里引用大佬的总结。
输入 xcodebuild -h 可以查看帮助。
Usage: xcodebuild [-project <projectname>] [[-target <targetname>]...|-alltargets] [-configuration <configurationname>] [-arch <architecture>]... [-sdk [<sdkname>|<sdkpath>]] [-showBuildSettings] [<buildsetting>=<value>]... [<buildaction>]...
xcodebuild [-project <projectname>] -scheme <schemeName> [-destination <destinationspecifier>]... [-configuration <configurationname>] [-arch <architecture>]... [-sdk [<sdkname>|<sdkpath>]] [-showBuildSettings] [<buildsetting>=<value>]... [<buildaction>]...
xcodebuild -workspace <workspacename> -scheme <schemeName> [-destination <destinationspecifier>]... [-configuration <configurationname>] [-arch <architecture>]... [-sdk [<sdkname>|<sdkpath>]] [-showBuildSettings] [<buildsetting>=<value>]... [<buildaction>]...
xcodebuild -version [-sdk [<sdkfullpath>|<sdkname>] [<infoitem>] ]
xcodebuild -list [[-project <projectname>]|[-workspace <workspacename>]] [-json]
xcodebuild -showsdks
xcodebuild -exportArchive -archivePath <xcarchivepath> -exportPath <destinationpath> -exportOptionsPlist <plistpath>
xcodebuild -exportLocalizations -localizationPath <path> -project <projectname> [-exportLanguage <targetlanguage>...]
xcodebuild -importLocalizations -localizationPath <path> -project <projectname>
复制代码
xcodebuild尝试
大家这时候可以新建一个项目 Test 。然后在Xcode中,把公司项目(有证书)的 Bundle Identifier 复制过来,这时候你会发现证书匹配通过了。(如果你没有证书,那看回证书知识,弄好再往下看)有了这个项目,就可以感受这些命令了。
打包方法一
笔者认为这方法不如方法二,而且苹果也废弃了其中一个工具。
先编译出.app,然后转成.ipa。
终端进项目文件夹后,先来试试第一条编译命令。
xcodebuild -project Test.xcodeproj -target Test -configuration Release 。
不出意外,会打印以上文字,包括签名身份和配置文件。文件夹下有 Test/build/Release-iphoneos/Test.app.dSYM 。
这时我们还要用 xcrun 命令把其导出为 ipa文件 ,(但xcrun在Xcode8.3废弃了,如果还要用看这篇 xcrun: error: unable to find utility "PackageApplication", not a developer tool or in PATH )
处理好后,执行下面命令转成 ipa 。
xcrun -sdk iphoneos PackageApplication build/Release-iphoneos/Test.app -o ~/Desktop/Test.ipa 复制代码
打包方法二
先用 archive ,然后 exprotArchive ,类似于手动打包的界面步骤。
(先运行 xcodebuild -list ,记住Scheme)
终端进入项目文件夹后,运行 xcodebuild archive -scheme Test -archivePath ~/Desktop/Test.xcarchive ,注意这里不打 scheme 会失败。
笔者瞎猜以上和Xcode内打包对应着这个界面。
从上图可看出,因为不同途径发布,所以要各自配置 ExportOptions.plist 。也就是用于 xcodebuild -exportArchive -archivePath <xcarchivepath> -exportPath <destinationpath> -exportOptionsPlist <plistpath> 中最后一个。
有两种途径配置。
- 通过手动打包,复制过去。
- 自己新建一个plist文件,加入相关键值对。(前提是你知道怎么加)。
ExportOptions.plist文件中有以下字段,配置如下:
method:字符串,为打包的类型,分为app-store,ad-hoc,enterprise和development,根据自己实际打包情况填写。
provisioningProfiles:字典,Xcode9需要,键值对为{bundleid:描述文件名},描述文件名最好使用其对应的UUID。
signingCertificate:证书类型,开发环境为iPhone Developer,生产环境为iPhone Distribution。
signingStyle:自动还是手动(manual与automatic),填写manual即可。
stripSwiftSymbols:填写为YES。
teamID:为开团队ID,在钥匙串中点击证书详情可以查看到。
uploadBitcode:为YES即可。
uploadSymbols:为YES即可。
复制代码
笔者还是建议手动打包,复制过去再做修改(以后其他项目只要稍微改动就能用,不用再次手动打包后复制)。因为通过图形界面,能更好理解这些字段的意义以及对应的操作。
笔者选取了 Enterprise 的截图。其他因为笔者没有证书,就靠各位尝试了。
然后终端中接着运行
xcodebuild -exportArchive -archivePath ~/Desktop/Test.xcarchive -exportPath ~/Desktop/Test.api -exportOptionsPlist ./ExportOptions.plist 复制代码
xcodebuild学到这就会打包了,其他不常用的方法,网上学习资源少,笔者也不想探究了。下面进入打包脚本。
自动打包脚本
笔者参考师兄@Tsui_YuenHong的文章 关于 iOS 批量打包的总结 ,自己设置了一份脚本,用了苹果建议的新方法以及补充了一些师兄脚本的不足点。
先说明一下笔者的悲惨遭遇。笔者以前也打过包上传App-Store,整个过程愉愉快快。但是这项目,一共有20多个包,更新一次版本经常动不动就打十多个包。这样打下来,头发就没了。由于代码基本是一样的,所以利用重签名,能极大程度缩短打包时间。
笔者的项目打包有以下需求。
简单点说就是针对不同的用户定制相应的自定义图标、功能等。
- 可以替换 bundle 信息
- 替换音频图片资源
- 可以执行不同代码
- 生成相应的plist文件
- 上传到蒲公英分发平台
思路:
defaults write
笔者遇到的问题:
切换图标的坑
先了解官方建议图标尺寸。当然其他尺寸,App图标也会接受,自动适应。
方案一(未解决)
- 笔者尝试用这种方案。原理就是用同名的图片覆盖包中的图片,重签名,达到修改图标的目的。但是包内图片覆盖以后,安装下来图标却没有改变(可能要修改Info.plist中的
Icon files (iOS 5)(然而这个字段就是AppIcon???不知道底层还有什么配置),笔者就不继续尝试了)。
方案二
- 此方法要把图标放在项目中,不要放在xcassets中。
-
AppIcon的名字一定要对应上!因为后面命令行
cp时要全部替换,否则难以预测会出现什么问题,就像下图。(笔者的项目中,只弄了60@2x和60@3x的图。) -
打包出来后,AppIcon图标在.app文件目录中,不在
BundleResources中。
关于可以执行不同代码。
重签名
建议大家先看这篇文章。 iOS应用程序的重签名(打包)
弄出来entitlements.plist,重签名要用到。
题外话
笔者重签名还是遇到了坑,打包出来的软件下载时进度条转了一圈,但无法最终完成。查了一段时间,才知道原因是重签名不成功。所以说脚本要重签名失败必须终止。
附带一篇iTunes降级文章,,PP助手好像没更新还是什么,只能用旧版iTunes来调试吧,真是累啊。 将 iTunes 降回 12.6.3 可下载应用安装包版本教程【Windows | Mac】
脚本
师兄的脚本一(运行时间256s)比笔者的脚本二(运行时间306s)快。
但脚本一采用的是苹果废弃的方法,以后出问题就试试脚本二吧。
两种脚本不同之处在于:脚本一先出来.app,后出来.ipa;脚本二先出来Archive包(包里有.app),后出来.ipa。
- 脚本一
准备好 Entitlements.plist (本文有获取教程,Cmd+f搜"重签名要用到")。并且确保本机能运行xcrun(本文Cmd+f搜"在Xcode8.3废弃")。
编译后用xcrun导出ipa,最后重签名。
脚本在师兄的文章 关于 iOS 批量打包的总结 里贴出来了。
笔者在用该脚本时遇到图标更换失败的问题,和脚本无关,与项目配置有关,解决方法看回上面。
但笔者认为该脚本存在一些问题的。例如重签名等操作失败后未终止脚本,导致笔者上传到蒲公英后下载失败一头雾水。这问题很严重。不过只要适当判断,加个 exit 就能解决。
- 脚本二
准备好 Entitlements.plist (本文有获取教程,Cmd+f搜"重签名要用到")和 ExportOptions.plist ist``(本文有获取教程,Cmd+f搜"有两种途径配置")。
先用archive,然后exprotArchive(类似于手动打包流程),最后重签名。
下面贴出脚本,注意里面很多地方笔者用Project代替了。
# 1.Configuration Info
# 项目路径 需修改
projectDir="你的项目路径"
# 打包生成路径 建议桌面
ipaPath="ipa生成路径"
# 图标路径 需修改
iconPath="图标路径"
# 以下文件用于重签名生成ipa,需修改
Entitlements=$ipaPath/Entitlements.plist
ExportOptions=$ipaPath/ExportOptions.plist
# 版本号
bundleVersion="2.0.0"
# 选择打包序号 多选则以空格隔开 如("1" "2" "3")
appPackNum=("1" "2")
# 蒲公英分发参数 不分发可忽略 默认不分发 下面的两个KEY是默认测试的网址对应KEY
ISUPLOAD=0
USERKEY="xxx"
APIKEY="xxx"
# ---------------------------可选 如果需要替换 app 的 icon --------------------------------- #
# 配置App信息数组 格式:"AppName(和工程中appInfo.Plist对应)" "icon" "Url中的AppName"(因为AppName为中文,此处用英文)
#Schemes:
# 1.app1 app1Icon app1UrlName
# 2.app2 app2Icon app2UrlName
# 3.app3 app3Icon app3UrlName
# --------------------------------------------------------------------------------------- #
# 打包个数
appPackNumLength=${#appPackNum[*]}
appInfos=(
"app1" "app1Icon" "app1UrlName"
"app2" "app2Icon" "app2UrlName"
"app3" "app3Icon" "app3UrlName"
)
appInfosLength=${#appInfos[*]}
# Scheme Name
schemeName="xx"
# 开始时间
beginTime=`date +%s`
# 生成 xcarchive 路径,建议桌面
mkdir ${ipaPath}/Payload
rm -rf ${ipaPath}/Payload/*
buildDir="${ipaPath}/Payload"
# 使用的时候要关掉自动签名 改为手动签名
# Build 生成 xcarchive
xcodebuild archive -workspace ${projectDir}/YouXiaoYun.xcworkspace -scheme ${schemeName} -archivePath ${buildDir}/Project.xcarchive
#
if [[ $? = 0 ]]; then # $? 表示上一条命令返回值。如果上一条命令成功执行,返回0,否则返回1.
echo "\033[31m 编译成功\n \033[0m"
else
echo "\033[31m 编译失败\n \033[0m"
exit 0
fi
# 创建打包目录
mkdir ${ipaPath}/AllPack
# 本地存放全部 IPA 的路径
allIPAPackPath="${ipaPath}/allPack"
# 以下二选一
# 1.----全部打包----
#for (( i=0; i<appInfosLength; i+=3 )); do
# 2.----自定义打包----
for (( j=0; j<$appPackNumLength; j++)); do i=`expr ${appPackNum[$j]} - 1` i=`expr $i \* 3`
# App Bundle Name (CFBundleName)
appName=${appInfos[${i}]}
# App DisPlay Name
appDisplayName=${appInfos[${i}]}
# App Icon Name
appIconName=${appInfos[$i+1]}
# App Download Name
appDownloadName=${appInfos[$i+2]}
# 创建不同 app ipa 目录
mkdir $allIPAPackPath/$appName
rm -rf $allIPAPackPath/$appName/*
echo "\033[31m appName:$appName appIconName:$appIconName appDownloadName:$appDownloadName\n \033[0m"
# 将对应的 icon 复制到需要修改的 app 的目录下
cp -Rf $iconPath/$appName/* ${buildDir}/Project.xcarchive/Products/Applications/Project.app
if [[ $? = 0 ]]; then
echo "\033[31m $appName 修改 icon 成功\033[0m"
else
echo "\033[31m $appName 修改 icon 失败\033[0m"
exit 0
fi
# 修改 Plist
defaults write $ipaPath/Payload/xx.app/info.plist "CFBundleName" $appName
defaults write $ipaPath/Payload/xx.app/info.plist "CFBundleDisplayName" $appDisplayName
if [[ $? = 0 ]]; then
echo "\033[31m $appName 修改 Plist 成功\033[0m"
else
echo "\033[31m $appName 修改 Plist 失败\033[0m"
exit 0
fi
# 重签名
xattr -cr ${buildDir}/Project.xcarchive/Products/Applications/Project.app
codesign -f -s "xx co., LTD" --entitlements $Entitlements ${buildDir}/Project.xcarchive/Products/Applications/Project.app
if [[ $? = 0 ]]; then
echo "\033[31m $appName 重签名成功\n \033[0m"
else
echo "\033[31m $appName 重签名失败\n \033[0m"
exit 0
fi
# 生成 ipa
xcodebuild -exportArchive -archivePath $ipaPath/Payload/Project.xcarchive -exportPath ${ipaPath}/$appDownloadName.ipa -exportOptionsPlist $ExportOptions
if [[ $? = 0 ]]; then
echo "\033[31m \n $appName 生成 IPA 成功 \n\n\n\n\n\033[0m"
else
echo "\033[31m \n $appName 生成 IPA 失败 \n\n\n\n\n\033[0m"
exit 0
fi
# 创建 Plist
plist_path=$allIPAPackPath/$appName/$appDownloadName.plist
cat << EOF > $plist_path
<?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>items</key>
<array>
<dict>
<key>assets</key>
<array>
<dict>
<key>kind</key>
<string>software-package</string>
<key>url</key>
<string>https://xxxxxxxxxxxx/$appDownloadName.ipa</string>
</dict>
<dict>
<key>kind</key>
<string>display-image</string>
<key>url</key>
<string>https://xxxxxxxxxxxx/${appIconName}.png</string>
</dict>
<dict>
<key>kind</key>
<string>full-size-image</string>
<key>url</key>
<string>https://xxxxxxxxxxxx/${appIconName}.png</string>
</dict>
</array>
<key>metadata</key>
<dict>
<key>bundle-identifier</key>
<string>你的bundid</string>
<key>bundle-version</key>
<string>$bundleVersion</string>
<key>kind</key>
<string>software</string>
<key>title</key>
<string>$appDownloadName</string>
</dict>
</dict>
</array>
</dict>
</plist>
EOF
# 移动
mv ${ipaPath}/$appDownloadName.ipa ${allIPAPackPath}/$appName
done
# 6.上传蒲公英分发平台
if [[ $ISUPLOAD = 1 ]]; then
echo "\n 开始上传蒲公英... \n"
curl -F "file=@$AllIPAPackPath/$appName/$appDownloadName.ipa/Project.ipa" \
-F "uKey=$USERKEY" \
-F "_api_key=$APIKEY"\
http://www.pgyer.com/apiv1/app/upload
#判断上传结果
if [[ $? = 0 ]]; then
echo "\n ~~~~~~~\^o^/~~~~上传到蒲公英成功~~~~\^o^/~~~ \n"
else
echo "\n ~~~~~\(╯-╰)/~~~~~~~上传到蒲公英失败~~~~~\(╯-╰)/~~~~~ \n"
fi
fi
# 清除无关文件
rm -rf $ipaPath/Payload
# 结束时间
endTime=`date +%s`
echo -e "打包时间$[ endTime - beginTime ]秒"
复制代码
参考
以上所述就是小编给大家介绍的《iOS —— 两套自动打包脚本》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- iOS自动打包并发布脚本
- iOS分享一个ipa打包脚本
- iOS定制化的自动打包脚本
- 使用 Fastlane 实现 iOS 跟 Android 自动打包脚本
- 后台管理系统 icec v1.1 发布,完善打包部署脚本
- 【Flutter】如何写一个Flutter自动打包成iOS代码模块的脚本
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Hit Refresh
Satya Nadella、Greg Shaw / HarperBusiness / 2017-9-26 / USD 20.37
Hit Refresh is about individual change, about the transformation happening inside of Microsoft and the technology that will soon impact all of our lives—the arrival of the most exciting and disruptive......一起来看看 《Hit Refresh》 这本书的介绍吧!