Xcode 多个 target 的管理

前言

工作中总会遇到一些这样那样的需求, 比如需要打包一个 Appstore版 + 企业版. 但是却总要手动修改 Bundle Id 等等的这些信息, 比较麻烦(当然马甲包也可以这么搞),最重要的万一某一个宏忘记手动切换了,但是测试又没测出来就上架了 Appstore ,那问题就大了. 于是就有了这篇文章.

简介

这里用到的方法主要是对 target 进行复制, 并且使用脚本自动化的修改条件宏来通过 条件编译 达到我们的目的.

复制 target

右键点击需要复制的 target, 点击 Duplicate.就会复制出一份新的 target.

复制 Target

此时选择新的 target 编译运行正常情况是能够直接通过的.

Target 的配置

复制一些需要区别配置或者不同代码的文件.


复制项目相关的文件
  • AppDelegate 需要配置一些第三方的 key.比如友盟 个推等.为了避免麻烦我直接拿出来分别写
  • Assets.xcassets 里面有不同的图片资源, 也需要复制一份.
  • Info.plist 工程一些配置信息.
  • main.m 里面需要配置 AppDelegate .(下面会讲)
  • Main.Storyboard
  • LaunchScreen.storyboard

根据自身需求决定哪些文件需要 copy 新的.

文件配置

因为同一个工程内部不能有 同名的类 , 所以复制出来的 AppDelegate 需要修改一下名称 比如 NewAppDelegate.这里就用到了 main.m.
需要在 main.m 中做如下修改:

int main(int argc, char * argv[]) {
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([NewAppDelegate class]));
    }
}
类/文件的归属配置:

这里是重点,配置不对将会很麻烦,甚至导致工程跑步起来.
此处以 main.m 为例:
选中 main.m 文件之后, Xcode 右侧区域中会出现 Target Membership 栏目. 如图所示:
此时选中的 target 就是该文件的归属, 通俗点就是在哪个 target 里面生效.
同一个文件也可以同时归属多个 target.

文件归属的设置

大部分文件都可以通过这种方式来设置. 比如: class, xib, storyboard, xcassets 等.

如果编译时候某个类找不到了,就可以在这个地方把对应的 target 勾选中就可以了.

条件宏的自动化

分别创建宏的 头文件 Config.h 和 脚本文件 Config.sh.

配置脚本

Build Phases 中点击左上角 + 新建一个 Run Script.

添加脚本

在如图的位置写上执行脚本的路径

配置脚本文件路径
// $PROJECT_DIR 是工程根目录, 根据情况来写
$PROJECT_DIR/Config/Config.sh

脚本

Config.sh 中写入如下脚本:

// 开关配置的头文件路径, 根据情况来
HeaderPath=$SRCROOT/Config/ProjectConfig.h
// 通过判断 Bundle Id 来区分当前编译的是哪个 Target
if [ $PRODUCT_BUNDLE_IDENTIFIER == "com.example.app1" ]; then
    // 把开关宏的值输入到配置文件内
    echo "#define TARGET_SWITCH 0" '// app1'  > $HeaderPath
elif [ $PRODUCT_BUNDLE_IDENTIFIER == "com.example.app2" ]; then
    echo "#define TARGET_SWITCH 1" '// app2' > $HeaderPath
elif [ $PRODUCT_BUNDLE_IDENTIFIER == "com.example.app3" ]; then
    echo "#define TARGET_SWITCH 2" '// app2' > $HeaderPath
else
    echo "// 未配置" > $HeaderPath
fi

此时选择不同的 target , 不管Run 还是 Build, 在 Config.h 中就会自动在

#define TARGET_SWITCH 0
#define TARGET_SWITCH 1
...
#define TARGET_SWITCH n

之间自动切换了.

脚本的原理就是判断不同 target 的 bundle id 在 Config.h 写入不同的宏.
关于脚本怎么写, 可以自己学习一下 Shell

结束

到此, 你就可以根据 TARGET_SWITCH 的值来对不同的 target 区别编译不同的代码了.

补充: 虽然这个比较方便,但是却有可能因为某一个 target 的代码无法编译通过而导致其他的 target 也无法编译通过,因此要做好不同 target 代码的屏蔽.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容