App 多渠道打包及重签名方案

欢迎访问我的博客原文

众所周知,渠道包是国内 Android 应用市场中常用的分发方式。渠道包中会包含不同的渠道信息,方便我们后续统计 App 在各分发渠道的下载量、用户量、留存率等,有针对地调整应用内容或是推广方案等。随着国内 iOS 应用上架越来越难,衍生出了很多企业包,为了方便采集数据,也会用多渠道的方案。

另外,项目进展过程中,可能会出现一些临时新增渠道的需求,这时回到工程中重新打包是比较费时的,有没有办法加快打包速度呢?下文中分享了一些方案。

iOS 多渠道打包方案

iOS 打渠道包目前想到的就只有两种方式,一种是通过多 target 方式,另一种是修改 plist 文件方式。

多 target 方式

点击项目中的 target,右键选择 Duplicate。可以修改下图标红框的三处:target 名称、plist 名称和 scheme 名称。

image

判断当前是哪个 target,可以通过添加宏定义实现,方式就是在 Build Settings 找到 Preprocessor Macros,填入宏定义名。

代码中这样判断:

#ifdef  TARGET1MACROS
    // target1
#elif defined TARGET2MACROS
    // target2
#endif

具体打包脚本就不介绍了,读者可以自行网上搜索,这种方式的缺点是一个渠道打一次,效率较低。下面着重分享修改 plist 的批量打包方式。

修改 plist 方式

下面用一个简单的 Demo 演示一下:

第一步:创建工程名为 MultiChannelDemo 的项目,并在项目中新建一个 Channel.plist 文件,plist 中设置 Channel 字段,值为 channel01。然后在页面上设置一个 label 标签用于显示当前的渠道名称,渠道名可以通过下面的代码获取到:

NSDictionary *channelDic = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Channel" ofType:@"plist"]];
NSString *channel = channelDic[@"Channel"];

第二步:把这个项目用可用的证书正常打一个母包,解压这个 ipa 包可以获得一个名为 Payload 的文件夹,里面是一个 .app 文件,右键显示其包内容,内容如下:

├── Base.lproj
├── Channel.plist
├── Info.plist
├── MultiChannelDemo
├── PkgInfo
├── _CodeSignature
└── embedded.mobileprovision

可以看到,里面的 Channel.plist 也就是在前面工程中新建的存储渠道信息的 plist,我们会修改里面的 Channel 再生成新的渠道包。

第三步:提取描述文件用于重签名,上一步中 Payload 的文件夹里有一个 embedded.mobileprovision 文件,这就是我们需要的文件。

第四步:新建一个纯文本,里面输入你要新增的渠道号,如:

image

第五步:写一个脚本文件 ChannelPackage.sh,内容如下:

#!/bin/bash

# 输入的包名

name="MultiChannelDemo"

echo "------SDK渠道包----------"

appName="${name}.app"

plistBuddy="/usr/libexec/PlistBuddy"

configName="Payload/${appName}/Channel.plist"

ipa="${name}.ipa"

# 输出的新包所在的文件夹名

outUpdateAppDir="ChannelPackages"

# entitlements.plist路径

entitlementsDir="entitlements.plist"

# 切换到当前目录

currDir=${PWD}

cd ${currDir}

echo "-----${currDir}"

rm -rf Payload

# 解压缩-o:覆盖文件 -q:不显示解压过程

unzip -o -q ${ipa}

# 删除旧的文件夹,重新生成

rm -rf ${outUpdateAppDir}

mkdir ${outUpdateAppDir}

# 删除旧的 entitlements.plist,重新生成

rm -rf ${entitlementsDir}

/usr/libexec/PlistBuddy -x -c "print :Entitlements " /dev/stdin <<< $(security cms -D -i Payload/${appName}/embedded.mobileprovision) > entitlements.plist

echo "------------------------开始打包程序------------------------"

# 渠道列表文件开始打包

for line in $(cat ChannelList.txt)

# 循环数组,修改渠道信息

do

# 修改 plist 中的 Channel 值

$plistBuddy -c "Set :Channel $line" ${configName}

# app 重签名

rm -rf Payload/${appName}/_CodeSignature

cp embedded.mobileprovision "Payload/${appName}/embedded.mobileprovision"

# 填入可用的证书 ID

codesign -f -s "iPhone Distribution: XXXXXX." Payload/${appName}  --entitlements ${entitlementsDir}

# 若输出 Payload/MultiChannelDemo.app: replacing existing signature 说明重签名完成

# 压缩 -r:递归处理,将指定目录下的所有文件和子目录一并处理 -q:不显示处理过程

zip -rq "${outUpdateAppDir}/$line.ipa" Payload

echo "........渠道${line}打包已完成"

done

脚本里的信息请根据你实际情况修改。到这里准备工作都完成了,需要的文件如下:

├── ChannelList.txt
├── ChannelPackage.sh
├── MultiChannelDemo.ipa
└── embedded.mobileprovision

第六步:在当前目录下执行脚本文件:

sh ChannelPackage.sh

打包完成后生成的 ChannelPackages 文件夹下,就是我们需要的渠道包:

├── ChannelList.txt
├── ChannelPackage.sh
├── ChannelPackages
│   ├── channel02.ipa
│   ├── channel03.ipa
│   └── channel04.ipa
├── MultiChannelDemo.ipa
├── Payload
│   └── MultiChannelDemo.app
├── embedded.mobileprovision
└── entitlements.plist

这种自动化打包的方式,可以规避掉 Xcode 本身打包编译的部分时间,快速出包。

Android 多渠道打包方案

下文介绍的是美团技术团队开源的 Walle,它有 Gradle 插件和命令行两种使用方式,前者快速集成,后者满足自定义需求。

Gladle 插件方式

配置 build.gradle

在项目根目录下的 build.gradle 文件中添加 Walle 插件依赖:

buildscript {
    dependencies {
        classpath 'com.meituan.android.walle:plugin:1.1.6'
    }
}

在 app 目录下的 build.gradle 文件中 apply 插件:

apply plugin: 'walle'

dependencies {
    compile 'com.meituan.android.walle:library:1.1.6'
}

配置插件

在 app 目录下的 build.gradle 文件中进行渠道配置:

walle {
    // 指定渠道包的输出路径
    apkOutputFolder = new File("${project.buildDir}/outputs/channels");
    // 定制渠道包的APK的文件名称
    apkFileNameFormat = '${appName}_v${versionName}_${channel}.apk';
    // 渠道配置文件
    channelFile = new File("${project.getProjectDir()}/channel")
}

渠道配置文件里的内容格式详见:渠道配置文件示例

如何获取渠道信息

在需要填写渠道信息的地方引用这段代码:

String channel = WalleChannelReader.getChannel(this.getApplicationContext());

如何生成渠道包

assemble${variantName}Channels 指令,导出 apk 包。

命令行方式

通过命令行方式,可以不打开 IDE,直接导出新渠道的 apk。步骤如下:

首先,新建一个文件夹,取用一个上面步骤导出的 apk 包,再下载 walle-cli-all.jar,两者都放置在这个文件夹目录下。

然后,在文件夹目录下执行命令:

java -jar walle-cli-all.jar put -c ${channelName} ${apkName}.apk

若上面的命令执行成功,会在当前目录下生成新的渠道包,名称为 ${apkName}_${channelName}.apk

如果要批量写入渠道,可以这样,渠道之间用逗号隔开:

java -jar walle-cli-all.jar batch -c ${channelName0},${channelName1},${channelName2} ${apkName}.apk

或者指定渠道配置文件:

java -jar walle-cli-all.jar batch -c ${channelFile} ${apkName}.apk

如果要写入额外信息,参考官方文档

如果要检查/显示渠道,命令为:

java -jar walle-cli-all.jar show ${apkName}.apk

Walle 现在既能满足新应用签名方案对安全性的要求,也能满足对渠道包打包时间的要求,有需要的可以尝试。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容