The original address of my blog
As we all know, channel package is a common distribution method in the Domestic Android application market. The channel package will contain different channel information, so that we can make follow-up statistics on the downloads, users and retention rate of the App in various distribution channels, and adjust the application content or promotion plan accordingly. As it is more and more difficult for iOS apps to be launched in China, many enterprise packages have been derived. In order to facilitate data collection, multi-channel schemes are also used.
In addition, during the progress of the project, there may be some demands for temporary new channels, and it will be time-consuming to go back to the project to repackage. Is there any way to speed up the packaging? Some of the options are shared below.
IOS multi-channel packaging solution
At present, there are only two ways of iOS channel package, one is through multiple targets, the other is to modify the plist file.
Multiple target way
Click Target in the project and right-click Duplicate. You can modify the target name, PList name, and Scheme name in the red box.
You can determine the current target by adding a macro definition by going to the Preprocessor Macros in Build Settings and filling in the macro definition name.
The code looks like this:
#ifdef TARGET1MACROS
// target1
#elif defined TARGET2MACROS
// target2
#endif
Copy the code
Specific package script is not introduced, readers can search online, the disadvantage of this way is a channel to play once, low efficiency. The following focuses on changing the batch packaging mode of PList.
Change the PLIST mode
Here’s a simple Demo:
Step 1: Create a project named MultiChannelDemo and create a channel. plist file in the project. Set the Channel field to channel01. Then set a label label on the page to display the current channel name, which can be obtained using the following code:
NSDictionary *channelDic = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Channel" ofType:@"plist"]];
NSString *channel = channelDic[@"Channel"];
Copy the code
Step 2: Create a parent package for this project with the available certificate. Unzip the ipA package and you can get a folder named Payload.
├ ─ ─ Base. Lproj ├ ─ ─ Channel. The plist ├ ─ ─ the Info. The plist ├ ─ ─ MultiChannelDemo ├ ─ ─ PkgInfo ├ ─ ─ _CodeSignature └ ─ ─ embedded.mobileprovisionCopy the code
As you can see, channel. plist is the plist that stores the Channel information created in the previous project. We will modify the Channel to generate a new Channel package.
Step 3: Extract the description file for re-signing. The folder Payload in the previous step contains the Embedded. Mobileprovision file.
Step 4: Create a new plain text and enter the channel number you want to add, such as:
Step 5: Create a script file, channelpackage. sh, that reads as follows:
#! /bin/bash
Enter the package name
name="MultiChannelDemo"
echo "------SDK channel package ----------"
appName="${name}.app"
plistBuddy="/usr/libexec/PlistBuddy"
configName="Payload/${appName}/Channel.plist"
ipa="${name}.ipa"
The name of the folder in which the new package is exported
outUpdateAppDir="ChannelPackages"
# entitlements. Plist path
entitlementsDir="entitlements.plist"
Switch to the current directory
currDir=${PWD}
cd ${currDir}
echo "-- -- -- -- --${currDir}"
rm -rf Payload
-o: overwrites the file. -q: does not show the decompression process
unzip -o -q ${ipa}
Delete the old folder and rebuild it
rm -rf ${outUpdateAppDir}
mkdir ${outUpdateAppDir}
# delete old entitlements. Plist, re generated
rm -rf ${entitlementsDir}
/usr/libexec/PlistBuddy -x -c "print :Entitlements " /dev/stdin <<< $(security cms -D -i Payload/${appName}/embedded.mobileprovision) > entitlements.plist
echo "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- start packing process -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --"
# Channel list file start packing
for line in $(cat ChannelList.txt)
# loop array, modify channel information
do
# change Channel in plist
$plistBuddy -c "Set :Channel $line" ${configName}
# app re-sign
rm -rf Payload/${appName}/_CodeSignature
cp embedded.mobileprovision "Payload/${appName}/embedded.mobileprovision"
Enter an available certificate ID
codesign -f -s "iPhone Distribution: XXXXXX." Payload/${appName} --entitlements ${entitlementsDir}
# if the output content/MultiChannelDemo. App: replacing existing signature shows heavy signature
-r: indicates that all files and subdirectories in the specified directory are processed at the same time. -q: indicates that the processing process is not displayed
zip -rq "${outUpdateAppDir}/$line.ipa" Payload
echo "... channel${line}Packing is complete."
done
Copy the code
Please modify the information in the script according to your actual situation. All the preparations have been completed and the required documents are as follows:
├── Bass Exercises ── Bass Exercises ── bass Exercises ── bass Exercises ── Bass ExercisesCopy the code
Step 6: Execute the script file in the current directory:
sh ChannelPackage.sh
Copy the code
The generated ChannelPackages folder after the package is completed is the channel package we need:
├ ─ ─ ChannelList. TXT ├ ─ ─ ChannelPackage. Sh ├ ─ ─ ChannelPackages │ ├ ─ ─ channel02. Ipa │ ├ ─ ─ channel03. Ipa │ └ ─ ─ ├── Heavy Bass Exercises ── Heavy Bass Exercises ── Heavy Bass Exercises ── entitlements.plistCopy the code
This way of automatic packaging can avoid part of Xcode packaging compilation time, fast package out.
Android multi-channel packaging solution
The following is an open source Walle from Meituan Technology team. It has Gradle plug-in and command line. The former can be integrated quickly, and the latter can meet the needs of customization.
Gladle plug-in mode
To configure the build. Gradle
Add the Walle plugin dependency to the build.gradle file in the project root directory:
buildscript {
dependencies {
classpath 'com. At meituan. Android. Walle: plugin: 1.1.6'}}Copy the code
Build. Gradle file in app directory:
apply plugin: 'walle'
dependencies {
compile 'com. At meituan. Android. Walle: library: 1.1.6'
}
Copy the code
Configure the plug-in
Configure channels in build.gradle file in app directory:
walle {
// Specify the output path of the channel package
apkOutputFolder = new File("${project.buildDir}/outputs/channels");
// The APK file name of the custom channel package
apkFileNameFormat = '${appName}_v${versionName}_${channel}.apk';
// Channel configuration file
channelFile = new File("${project.getProjectDir()}/channel")}Copy the code
For details about the format of a channel profile, see Channel Profile Example.
How to obtain channel information
Quote this code where you need to fill in channel information:
String channel = WalleChannelReader.getChannel(this.getApplicationContext());
Copy the code
How to generate channel packages
Export the APK package with the Assemble ${variantName}Channels directive.
Command-line mode
From the command line, you can export the APK of the new channel without opening the IDE. The steps are as follows:
First, create a folder, grab one of the APK packages exported in the previous steps, and then download Walle-cli-all.jar, both placed in this folder directory.
Then, execute the command under the folder directory:
java -jar walle-cli-all.jar put -c ${channelName} ${apkName}.apk
Copy the code
If the preceding command is executed successfully, a new channel package named ${apkName}_${channelName}.apk is generated in the current directory
If you want to write channels in batches, separate them with commas:
java -jar walle-cli-all.jar batch -c ${channelName0}.${channelName1}.${channelName2} ${apkName}.apk
Copy the code
Or specify a channel profile:
java -jar walle-cli-all.jar batch -c ${channelFile} ${apkName}.apk
Copy the code
For additional information, refer to the official documentation.
To check/display channels, the command is:
java -jar walle-cli-all.jar show ${apkName}.apk
Copy the code
Walle can now meet the security requirements of the new application signature scheme, and also meet the requirements of channel package packaging time. If you need it, you can try it.