iOS进阶_多Target

[TOC]

利用多Target开发相似app

一、问题背景

开发一个与之前几乎一样的app。只是app名字等基本信息变更。

错误做法 正确做法
项目 再创建了新的项目 使用同一项目
原因 极容易出现后来新开发的功能两个app都要支持 保证可共用到以后新开发的功能

下面我们开始介绍如何利用多Target开发相似app。

二、操作步骤

1、生成新的Target(这里推荐采用Duplicate方式,而不是File->New->Target)

1.1、Duplicate方法略。
1.2、Duplicate后,需要修改的东西
必选需修改项 操作方法 得到
Info.plist ①复制一份。
②并重新为Target选择Info.plist
③跟新Info.plist中的名字、签名等
App1Info.plist、App2Info.plist
Scheme Manager Scheme -> 双击重命名 新的App2Scheme
证书&描述文件 更具新的BundleId,添加证书&描述文件 真机编译通过

特别注意:add Info.plist等文件的时候,一定要注意选择对应的Target。不多多勾选☑️,也不要少勾选。

1.3、其他APP定制项更改
可选修改项 操作方法 得到
icon 修改InfoPlist 新APP的Icon
名字 修改InfoPlist 新APP的名字

2、Target区分

需求背景:有些共用的文件在不同的Target下是有细微不同的,那么我们在具体实现的时候就需要作出区分。

2.1、Objective-C、C、C++的LLVM预处理宏的添加

Objective-C、C、C++的LLVM预处理宏在Preprocessor Macros处定义。如图创建工程时已经默认创建好了在Debug时定义DEBUG=1 宏标记。

2.2、Swift

因为Swift 中没有宏定义的概念,因此我们不能使用 #ifdef 的方法来检查某个符号是否经过宏定义。

在项目的 Build Settings 中,找到 Swift Compiler - Custom Flags,并在其中的 Other Swift Flags

为APP1加上 -D APPTARGET1 就可以了;为APP2加上 -D APPTARGET2 就可以了;

其他参考文章:https://blog.csdn.net/kaiyuanheshang/article/details/78862382

解决办法:这里解决的方法是针对不同的Target在Preprocessor Macros中定义宏,如添加TargetTYPE

  • 在Preprocessor Macros中添加TARGETTYPE

PreprocessorMacros添加后

Target代码区分需用到的知识:

含义 示例
#if 既关心宏是否定义,又关心宏的逻辑的真假
#ifdef
#ifndef
仅仅关心宏是否被定义,不关心宏的逻辑真假

代码区分如下:

1
2
3
4
5
#if TARGETTYPE == 0
[AMapServices sharedServices].apiKey = @"6d79992bc988b60f68e059edeef82538";
#elif TARGETTYPE == 1
[AMapServices sharedServices].apiKey = @"aef6d9dabe4cdd1da9e923e52b5d40ca";
#endif

至此,你直接编译,发现”好像”完成了。实际上如果你的项目没有使用POD的,确实是到此就完成了 。

分割图1

下面我们额外补充,当你的项目有使用POD的时候,你还需要处理的东西。

3、Pod修改

在上述中,你可能发现好像我使用了POD的但是依然正确编译通过啊。

是的,是通过了,但是这是假象。或者准确的说,当你下次使用POD相关命令,如pod install的时候,你会发现之前的项目编译不通过了。

所以,你需要修改PodFile,并重新pod install。PodFile的修改方法如下:

1
2
3
4
5
6
7
8
9
target 'APP1' do
pod 'AFNetworking'
pod 'APP1SDK'
end

target 'APP2' do
pod 'AFNetworking'
pod 'APP2SDK'
end
  • 修改方式1:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# There are no targets called "APPCommon" in any Xcode projects
abstract_target 'APPCommon' do
pod 'AFNetworking'

# Has its own copy of APPCommon + APP2SDK
target 'APP1' do
pod 'APP1SDK'
end

# Has its own copy of APPCommon + APP2SDK
target 'APP2' do
pod 'APP2SDK'
end
end
  • 修改方式2:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 共用的第三方库
def AppCommon_Pods
pod 'AFNetworking'
end

# APP1所需的第三方库
target 'APP1' do
AppCommon_Pods
pod 'APP1SDK'
end

# APP2所需的第三方库
target 'APP2' do
AppCommon_Pods
pod 'APP2SDK'
end

最后修改完后,重新pod install后即可。

分割图1

4、脚本打包时候,因为多Target后旧的libPods-xxx(Framework)忘删除引起的问题

多Target后旧的libPods-xxx引起的问题

多Target后旧的libPods-xxx引起的问题

多Target后旧的libPods-xxx的问题解决否的判断

多Target后旧的libPods-xxx的问题解决否的判断

三、Swift中的条件编译

在C 系语言中,我们可以通过预处理宏定义一些参数,使用#if或者#ifdef编译条件分支来控制哪些代码需要编译,而哪些代码不需要。但是在swift中没有宏定义的概念,虽然不能使用 #ifdef 的方法来检查某个符号是否经过宏定义,但是可以支持“#if/#else/#endif”语句。

四、其他

只用一个target,配合一个脚本,可以进行茫茫多target的管理了