思维导图
Xcode 默认配置
Xcode 在生成项目时已经帮我们配置好了两个环境,并且已经在同一个scheme下做好了配置:
#Debug
测试环境,一般 Build、Run、Test 和 Analyze,都在这个环境中进行。
#Release
生产环境,Profile 和 Archive 打包上传商店时,使用这个环境。
查看Build Settings
,你能看到每个设置下都分两种环境,可以做不同的设置。
有时我们需要的不止这两种环境,可能还需要企业版,又或者需要刷排名引流,这时就需要我们自己配置这些分包了。分包配置的大致原理是:同一个 TARGET
中设置不同的 Configurations
,从而区分各种环境。下面将介绍具体的配置步骤~
1.配置 PROJECT
1.1.info
PROJECT
->info
->Configurations
,点下方+
,复制一份Debug
或者Rlease
的配置,重新命名,如InHouse
。
1.2.Build Settings
PROJECT
->Build Settings
,点顶部搜索框左边的+
,Add User-Defined Settings,设置一个自定义的宏,如APP_NAME
,分别输入名称。
2.配置 TARGETS
TARGETS
会自动继承PROJECT
中的配置;反过来,对TARGETS
所做的修改并不会主动映射到PROJECT
中,需要手动复制。不复制也可以,不影响正常使用,因为 Xcode 会以TARGETS
中的配置为准。
2.1.Build Settings
TARGETS
->Build Settings
中翻到底,User-Defined
选项中自动继承了PROJECT
中APP_NAME
的配置。同样可以在这里点顶部的+
,Add User-Defined Settings,添加新的配置项,如APP_BUNDLE_ID
。在TARGETS
->info
中修改 Bundle display name 为${APP_NAME}
。这样就可以给不同分包起不同的名字,或者不同的 Bundle Identifier。
2.3.配置 preprocessor Macros
这是预处理的宏,后面代码中可作为标记
区分不同环境。可自行设置:
2.4.代码中使用
以 UIabel 上的文字显示为例,要求不同环境中显示对应的环境名:
1 2 3 4 5 6 7 8 9 10 11 12 13
| - #ifdef DEBUG _mLable.text = @"DEBUG"; #elif M_InHouse _mLable.text = @"InHouse"; #elif M_Release _mLable.text = @"Release"; #else _mLable.text = @"默认值"; #endif
|
这里就是通过使用#ifdef
、#elif
、#else
来判断是否有某个宏定义,而这些宏定义正是之前我们在 preprocessor Macros 中定义好的一些标记。运行查看效果即可~
3.配置 Scheme
Scheme
->Manage Schemes
->齿轮
,复制一份并重新命名为Release
或者InHouse
。
Edit Scheme
,将 Build/Run/Test/Profile/Analyze/Archive 的 Build Configuration 设置成PROJECT
中的 Configurations 中对应的名字,如Rlease
、InHouse
。
这一步配置 scheme 是为打包时更容易的区分环境,以防失误导致打错包。同时,如果你使用了脚本进行打包或者给不同分包替换图片素材时,也可以通过这个 scheme 进行区分。
4.配置 Pod 工程
如果工程集成了三方库,那么Pods
工程也需要针对分包进行配置:
这里的Configurations
与原工程中一致即可。
5.脚本替换素材
我的工程目录:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| . ├── AutoBuild │ ├── ExportOptions.plist │ ├── Header.plist │ ├── replace_res.sh │ └── res │ ├── drawable │ ├── icon │ └── launcher ├── Majia │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ └── LaunchImage.launchimage │ ├── Info.plist │ ├── main.m │ └── res ├── Majia.xcodeproj ├── Majia.xcworkspace ├── Podfile ├── Podfile.lock ├── Pods └──autobuild.sh
|
根据不同分包的需要,使用脚本替换素材replace_res.sh
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| #!/bin/sh
TARGET_SCHEMES=$1
if [ ! -n "$TARGET_SCHEMES" ]; then echo ">>>> TARGET_SCHEMES is missing!!!" exit fi
echo ">>>>>>>>>>>> Start replacing RES at $(date) <<<<<<<<<<<<<<<"
AUTOBUILD_PATH=$PWD PROJECT_ROOT_PATH="$AUTOBUILD_PATH/.."
EXPORT_ICON_PATH="$AUTOBUILD_PATH/res/icon" EXPORT_LAUNCHER_PATH="$AUTOBUILD_PATH/res/launcher" EXPORT_DRAWABLE_PATH="$AUTOBUILD_PATH/res/drawable"
ICON_ASSETS="$PROJECT_ROOT_PATH/Majia/Assets.xcassets/AppIcon.appiconset/" LAUNCHER_ASSETS="$PROJECT_ROOT_PATH/Majia/Assets.xcassets/LaunchImage.launchimage/" DRAWABLE_ASSETS="$PROJECT_ROOT_PATH/Majia/res/"
cp -R -a "$EXPORT_ICON_PATH/$TARGET_SCHEMES/." $ICON_ASSETS
cp -R -a "$EXPORT_LAUNCHER_PATH/$TARGET_SCHEMES/." $LAUNCHER_ASSETS
cp -R -a "$EXPORT_DRAWABLE_PATH/$TARGET_SCHEMES/." $DRAWABLE_ASSETS
echo ">>>>>>>>>>>> Finish replacing RES at $(date) <<<<<<<<<<<<<<<"
|
在终端里 cd 到根目录下的AutoBuild
目录执行该脚本:
1
| $./replace_res.sh InHouse
|
脚本后的参数是你想替换素材的分包scheme
。
6.脚本打包
cd 到根目录下,执行下面的打包脚本autobuild.sh
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
| #!/bin/sh
echo ">>>>>>>>>>>> Start at $(date) <<<<<<<<<<<<<<<"
PROJECT_ROOT_PATH=$PWD AUTOBUILD_PATH="$PROJECT_ROOT_PATH/AutoBuild"
CURRENT_DATE=$(date +%Y_%m%d_%H%M) WORKSPACE_NAME="Majia.xcworkspace"
HEADER_PLIST="$AUTOBUILD_PATH/Header.plist" EXPORT_PLIST="$AUTOBUILD_PATH/ExportOptions.plist"
KEY_SCHEME="KEY_SCHEME" KEY_APP_NAME="KEY_APP_NAME" KEY_TEAM_ID="KEY_TEAM_ID" KEY_DEV_ID="KEY_DEV_ID"
InHouse={$KEY_SCHEME:"InHouse",$KEY_APP_NAME:"InHouse",$KEY_TEAM_ID:"your_team_ID",$KEY_DEV_ID:"your_team"} Release={$KEY_SCHEME:"Release",$KEY_APP_NAME:"Release",$KEY_TEAM_ID:"your_team_ID",$KEY_DEV_ID:"your_team"}
FLAVORS=($Release,$InHouse)
parse_json(){ echo $1 | sed 's/.*'$2':\([^,}]*\).*/\1/' }
BUILD_DIR="$PROJECT_ROOT_PATH/Build" RELEASE_DIR="$BUILD_DIR/Products"
rm -rdf $BUILD_DIR
OUT_BINARY_DIR="$PROJECT_ROOT_PATH/binarys_$CURRENT_DATE"
if [ ! -d $OUT_BINARY_DIR ]; then mkdir $OUT_BINARY_DIR fi
for ((i = 0; i < ${#FLAVORS[@]}; i++)) do TARGET_SCHEMES=$(parse_json ${FLAVORS[$i]} $KEY_SCHEME) TARGET_APP_NAMES=$(parse_json ${FLAVORS[$i]} $KEY_APP_NAME) TARGET_TEAM_IDS=$(parse_json ${FLAVORS[$i]} $KEY_TEAM_ID) TARGET_DEV_IDS=$(parse_json ${FLAVORS[$i]} $KEY_DEV_ID)
rm $EXPORT_PLIST cat $HEADER_PLIST >> $EXPORT_PLIST echo "<plist version=\"1.0\">" >> $EXPORT_PLIST echo "<dict>" >> $EXPORT_PLIST echo "<key>teamID</key>" >> $EXPORT_PLIST echo "<string>$TARGET_TEAM_IDS</string>" >> $EXPORT_PLIST echo "<key>method</key>" >> $EXPORT_PLIST echo ">>>>>>>>>>>>>>>>>>>>>>>> target scheme $TARGET_SCHEMES" if [ $TARGET_SCHEMES = "InHouse" ]; then echo "<string>enterprise</string>" >> $EXPORT_PLIST echo ">>>>>>>>>>>>>>>>>>>>>>>> enterprise Done" else echo "<string>app-store</string>" >> $EXPORT_PLIST echo ">>>>>>>>>>>>>>>>>>>>>>>> app-store Done" fi echo "<key>uploadSymbols</key>" >> $EXPORT_PLIST echo "<true/>" >> $EXPORT_PLIST echo "</dict>" >> $EXPORT_PLIST echo "</plist>" >> $EXPORT_PLIST echo ">>>>>>>>>>>>>>>>>>>>>>>> Reset export options Done"
cd $AUTOBUILD_PATH ./replace_res.sh $TARGET_SCHEMES
cd $PROJECT_ROOT_PATH echo ">>>>>>>>>>>>>>>>>>>>>>>> Reset res Done" ARCHIVE_FILE="$OUT_BINARY_DIR/$TARGET_APP_NAMES.xcarchive" DSYMS_FILE="$TARGET_APP_NAMES.dSYMs.zip" xcodebuild -workspace $WORKSPACE_NAME -scheme $TARGET_SCHEMES -configuration $TARGET_APP_NAMES clean xcodebuild archive -workspace $WORKSPACE_NAME -scheme $TARGET_SCHEMES -configuration $TARGET_APP_NAMES -archivePath $ARCHIVE_FILE cd $ARCHIVE_FILE zip -r $DSYMS_FILE "dSYMs" mv $DSYMS_FILE $OUT_BINARY_DIR cd $PROJECT_ROOT_PATH xcodebuild -exportArchive -archivePath $ARCHIVE_FILE -exportPath $OUT_BINARY_DIR -exportOptionsPlist $EXPORT_PLIST echo "apple id paired" >> "$OUT_BINARY_DIR/$TARGET_APP_NAMES_$TARGET_DEV_IDS" echo ">>>>>>>>>>>>>>>>>>>>>>>> $TARGET_SCHEMES single loop Done" done
echo ">>>>>>>>>>>> Finish at $(date) <<<<<<<<<<<<<<<"
|
根据需要修改脚本中的 teamID 和开发者证书信息,修改将要打包的 scheme,cd 到工程根目录执行脚本:
此脚本做了以下几件事:
- 生成打包所需的 ExportOptions.plist;
- 自动执行
replace_res.sh
脚本替换素材,你无须手动执行了;
- 根据指定的
scheme
执行 archive;
- 导出
dSYM
文件;
- 导出 ipa。
7.小缺点
根据我自己的使用情况来看,配置过多分包时,在 Xcode 中打开Build Settings
会非常卡。这可能是因为 Xcode 中的各种配置从本质上来说都是保存在 plist 中,加载此配置文件时,要读取N个分包的节点,是需要花费一定时间。
相关参考:
#©项目代码