iOS--自动打包(兼容Xcode9)

#——————————————–
# 2018/05/16
# 版本:3.0.0
# 1. 自动匹配授权文件和签名(移除config.plist配置)
# 2. 优化授权文件匹配算法,取有效期最长授权文件
# 3. 调整脚本参数,详见-h
# 4. 优化代码
# 5. 兼容长参数
# 6. 增加全局配置文件user.xcconfig
#——————————————–

最新代码详见 github源码

下文是 开发IPABuildShell第一个版本写的,当前版本已经有很大的变化 -2018/05/16


前言

作为iOS开发者,每次真机测试我都习惯在Build Settings中设置签名信息Code Signing Identity 、Development Team、 Provisioning Profile、Provisioning Profile(Deprecated)等,并会在General中去掉勾选Automatically manage signning即设置为手动管理证书!所以,在实现自动打包脚本时,我也会通过修改这里的配置来完成所需的签名等配置。本文的目的主要是了解Xcode Project的配置是如何组织的,以及如何用脚本替我们完成Target的配置达到与手动配置一致的效果,其次是实现脚本自动打包功能! github源码

这里写图片描述

这里写图片描述


工欲善其事必先利其器

我们知道Xcode Project 的配置文件是project.pbxproj

  1. 如何更方便查看project.pbxproj文件

    这里写图片描述

  2. 以往很长一段时间,需要在project.pbxproj文件中查找或者编辑某些配置时我都会使用Subline Text、文本编辑器、xcode打开,他们的效果都一样。

    这里写图片描述

    这里写图片描述

  3. 上面的方式如果需要查找某个value或key的层级关系这就悲剧了,接近上万的行数!行数太多不能一屏看完,拖着拖着就不知道拖到那里了。
    这里写图片描述

  4. 如果project.pbxproj文件能像Plist文件那样展开浏览就好了,于是尝试修改project.pbxproj的后缀名字为”.plist”即project.plist,使用xcode双击打开!果然!!!果然!!!果然!!!舒服呀,是不是有种被治愈的感觉!
    这里写图片描述


探究project.pbxproj

对于以plist形式展示的project.pbxproj,强烈的激起了我对它的进一步分析的想法!

这里写图片描述

  1. 随意浏览了一下,发现:rootObject :0CA805261D7D1A1900EEC7DA
    这应该是个入口,下一步搜索”0CA805261D7D1A1900EEC7DA“
    这里写图片描述

  2. 这里的targets应该就是正好对应我们工程中的targets
    这里写图片描述

  3. 这里的ProvisioningStyle 应该就对应Target - General -Automatically manage signning
    这里写图片描述

  4. 继续搜索targets-item0对应的:0CA8052D1D7D1A1900EEC7DA
    这里写图片描述

  5. 上面搜索展示出得列表,从名字来看很容易就能猜测出来其代表的意义,buildConfigurationList应该就是配置列表了。搜索:buildConfigurationList:0CA805451D7D1A1900EEC7DA。
    这里写图片描述

  6. buildConfigurations的两个tiem其实分表达标release和debug配置,我们选择第一项继续搜索一下:0CA805461D7D1A1900EEC7DA
    这里写图片描述

由上图可以看出来,图中的key正好对应Xcode Project 中我们在Build Settings中所看到的选项配置!是否好奇,为什么在这里看到的配置那么少?经过测试,发现一些默认的配置,如果你在Xcode Project没有发生过修改,它是不会写在project.pbxproj中,所以我猜测就是这个原因了!至于Xcode Project 中的其他配置,按照上面的方法应该都可以在project.pbxproj中一一找到,这里就不重复了!

Let’s Talk About project.pbxproj文章中指出了project.pbxproj的内容规则

project.pbxproj 使用 UUID 作为交叉引用的索引,保证每个配置信息对象的唯一性。因为 UUID 根据机器硬件和时间戳生成,避免了多人在同一时间段操作修改工程文件带来的问题。也就是说工程中每项配置对象都有个唯一的 UUID,然后其他配置对象想引用某个配置对象直接使用它的 UUID 即可。这就跟我们编程时使用指针指向某个对象的地址一样,其他对象的属性想引用它,只需要给属性传个指针地址就行了。


利用脚本进行工程配置

涉及工具
工具 作用
PlistBuddy 读写mobileprovision格式的文件,即可授权文件
xcodebuild Xcode Project 构建
security 解码mobileprovision文件、获取可用签名列表
codesign 代码签名(此处值用来检查APP签名)
简单介绍PlistBuddy使用
PlistBuddy 使用冒号:来分割每个属性key的名字,例如下图假设需要获取name的值,那么冒号分割key的组成就是
:Objects:0C14C6811E4964FA00F40247:List:2:name

完整的命令就是:

/usr/libexec/PlistBuddy -c 'Print :Objects:0C14C6811E4964FA00F40247:List:2:name' $plistFile

这里写图片描述

使用/usr/libexec/PlistBuddy -h 可以看到帮助说明

Entry Format:
Entries consist of property key names delimited by colons. Array items
are specified by a zero-based integer index. Examples:
:CFBundleShortVersionString
:CFBundleDocumentTypes:2:CFBundleTypeExtensions


代码实现(最新代码详见 github源码

  • 帮助
  -p <Xcode Project File>: 指定Xcode project. 否则,脚本会在当前执行目录中查找Xcode Project 文件
  -g: 获取当前项目git的版本数量
  -l: 列举可用的codeSign identity.
  -x: 脚本执行调试模式.
  -b: 设置Bundle Id.
  -d: 设置debug模式,默认release模式.
  -t: 设置为测试(开发)环境,默认为生产环境.
    -r <体系结构>,例如:-r 'armv7'或者 -r 'arm64' 或者 -r 'armv7 arm64'  -c <development|app-store|enterprise>: development 内部分发,app-store商店分发,enterprise企业分发
  -h: 帮助.
  • 检查Xcode Project

    为了方便使用,可以通过-p指定xcode project文件。不使用-p参数,那么代码会自动在脚本执行目录中寻找xcode project文件。

##检查xcode project
function checkForProjectFile
{

    ##如果没有指定xcode项目,那么自行在当前目录寻找
    if [[ "$xcodeProject" == '' ]]; then
        pwd=`pwd`
        xcodeProject=`find "$pwd" -maxdepth 1  -type d -name "*.xcodeproj"`
    fi

    projectExtension=`basename "$xcodeProject" | cut -d'.' -f2`
    if [[ "$projectExtension" != "xcodeproj" ]]; then
        errorExit "Xcode project 应该带有.xcodeproj文件扩展,.${projectExtension}不是一个Xcode project扩展!"
    else
        projectFile="$xcodeProject/project.pbxproj"
        if [[ ! -f "$projectFile" ]]; then
            errorExit "项目文件:\"$projectFile\" 不存在"
        fi
        logit "发现pbxproj:\"$projectFile\""
    fi


}
  • 检查是否是workspace,

    因为xcodebuild 对于workspace的构建配置参数不一样,详见build函数!

function checkIsExistWorkplace
{
    xcworkspace=`find "$xcodeProject/.." -maxdepth 1  -type d -name "*.xcworkspace"`
    if [[ -d "$xcworkspace" ]]; then
        isExistXcWorkspace=true
        logit "发现xcworkspace:$xcworkspace"
    else
        isExistXcWorkspace=false;
    fi
}
  • 自动匹配授权文件
    通过参数-c <development|app-store|enterprise>: development 内部分发,app-store商店分发,enterprise企业分发参数指定的值,匹配对应的授权文件。
function autoMatchProvisionFile
{
    ##授权文件默认放置在和脚本同一个目录下的MobileProvisionFile 文件夹中
    mobileProvisionFileDir="$( cd "$( dirname "$0"  )" && pwd  )/MobileProvisionFile"
    if [[ ! -d "$mobileProvisionFileDir" ]]; then
        errorExit "授权文件目录${mobileProvisionFileDir}不存在!"
    fi

    matchMobileProvisionFile=''
    for file in ${mobileProvisionFileDir}/*.mobileprovision; do
        applicationIdentifier=`$plistBuddy -c 'Print :Entitlements:application-identifier' /dev/stdin <<< $($security cms -D -i "$file" 2>/tmp/log.txt )`
        applicationIdentifier=${applicationIdentifier#*.}
        if [[ "$appBundleId" == "$applicationIdentifier" ]]; then
            getProfileType $file
            if [[ "$profileType" == "$channel" ]]; then
                matchMobileProvisionFile=$file
                logit "授权文件匹配成功:${applicationIdentifier},路径:$file"
                profileTypeToName "${channel}"
                logit "授权文件分发渠道:$profileTypeName"
                break
            fi
        fi
    done

    if [[ $matchMobileProvisionFile == '' ]]; then
        profileTypeToName "${channel}"
        errorExit "无法匹配${appBundleId} 分发渠道为【${profileTypeName}】的授权文件"
    fi

    ##企业分发,那么检查授权文件有效期
    if [[ "$channel" == 'enterprise' ]];then
        getProvisionfileExpirationDays "$matchMobileProvisionFile"
        logit "授权文件有效时长:${expirationDays} 天";
        if [[ $expirationDays -lt 0 ]];then
            profileExpirationDa
  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值