背景:很多时候,我们需要在一个工程中创立多个target,也就是说我们希望同一份代码可以创建两个应用,放到模拟器或者真机上,或者是,我们平时有N多人合作开发,当测试的时候,在A这里装了一遍测A写的那块,当需要测试B写的代码时,我们需要到B那里去装一遍,如果只有一个target的话,那么A的将会被覆盖

还有些时候,我们需要确定到底是A的问题还是B的代码出了问题,这时候都需要建立一个工程能够编译多个版本出来,下文就介绍怎么在一个工程中编译多个版本
 
 
好了,闲话不多少,下面正式开始:
我们建立一个默认的应用来演示做法:
建立后的应用如下:
 
可以看到,上面只有一个target:即TestTarget,为了方便演示,我们给它加上一个多语言,让它在模拟器上的名字是中文
我们在工程的InfoPlist.strings中增加一句:CFBundleDisplayName="测试正式版”;
这样在模拟器中安装后显示的是
 
好了,前序工作已经可以了
 
1.新增一个target,因为这里我们是建立一个和原来基本一致的target,所以,我们这里可以选择复制来新建一个target
当你选择复制后,会多出两个文件,如下
还会在scheme那里多出一个和这个target相关的scheme
 
 
2.
上面的名字太难看,我们改个名字,改了名字后,你会发现
重新选择我们更改后名字的Info plist文件 TestTarget2-info.plist文件(文件名最好是包含info.plist,这个是一个约定,便于以后寻找这个文件)
我们将那个scheme也更改一下
 
还有生成的product的名字也要改一下,切换到TestTargetTest2的Build Settings下,搜索product name,将product name改成我们需要的名字(注意,这个名字只是我们生成的app的名字,不一定是最后的显示的名字,最后显示的名字还要看用户是否在InfoPlist.strings文件中设置了CFBundleDisplayName="测试1";)
 
 
 
3.切换到TestTargetTarget2这个scheme,运行,
看看模拟器中,你会发现
    模拟器中有两个测试1了,
 
有些同学在这里并没有生成两个 图标,这个应该是他将两个target的Bundle Identifier都设成了一样的,这个如果一样的话,那生成的target会覆盖上一次的
 
4.上面已经生成了两个target,并且也在模拟器上运行成功了,问题来了,我们怎么知道哪个是哪个呢,两个的名字是一样的,不要担心,这个问题很好解决的
 
由于共用了一个InfoPlist.stirngs文件,所以,才会出现两个target在模拟器上都显示为 测试1,知道了问题所在,那么下面我们就解决它,很显然,我们应该针对TestTargetTest2再建立一个InfoPlist.stirngs,
由于我们只是需要名字显示不同,其它都不需要改变的,所以我们可以直接进行复制,将工程目录下的所有的语言的 InfoPlist.strings文件复制一份,建立一个新的文件夹(注意,需要将所有语言的InfoPlist.strings都复制一份,因为多语言嘛,语言的文件夹也要有)
如图
由于我们这里,只有一种语言,
,所以我们targetTest2中只有一个en.lproj文件夹,将targetTest2文件夹下的InfoPlist.strings中的 
 
 
 
将刚添加的文件加到工程中来
添加完后,将原来那个Infoplist.stirngs的target中的targetTest2去掉如下图:
 
将目录targetTest2下的Infop.stirngs中的内容修改成 测试2
 
5.先选TestTarget这个scheme,运行,在模拟器上会出现 测试1,切换scheme为TestTarget2,运行,在模拟器上将生成 测试2
切换scheme如图
一切正确后在模拟器上将会显示
 
 
 
6.作为附录,其实也比较重要的是,我们很多target共用的代码,资源等,有时候我们在代码中需要区分到底是哪个target,比如说,我们生成的第二个target是一个受限版本,我们需要提示用户(比如是功能受限的免费版本),怎么在代码中区分呢?
有如下三个方式
第一种方式,利用CFBundleIdentifier来判断
  1. NSString*BundleIdentifier =[[[NSBundlemainBundle]infoDictionary]objectForKey:@"CFBundleIdentifier"];// Do any additional setup after loading the view, typically from a nib.
       
    if ([BundleIdentifierisEqualToString:@"yohunl.TestTarget2"])
    {
           
    //处理代码
           
    NSLog(@"TestTarget2-Info.plist");
        }
       
    else {
           
    //处理代码
           
    NSLog(@"TestTarget-Info.plist");
        }

    第二种方式,定义一个编译器宏,来进行区分,在
    打开TestTarget2,
注意,上面的 -D是需要的,一般我们对于这种定义宏都大写的
在代码中可以

#ifdef TARGET2
    //target2的处理代码
    NSLog(@"TARGET2");
#else
    NSLog(@"TARGET1");
#endif

 
 
第三种方式,这种不需要增加-D的
增加预编译宏
在代码中

#ifdef TESTTARGET2
    //target2的处理代码
    NSLog(@"TESTTARGET2");
#else
  
    NSLog(@"TARGET1");

#endif
 
以上三种方式都可以的
 
 
附录二:参考文献
 

《转》xcode创建一个工程的多个taget,便于测试和发布多个版本的更多相关文章

  1. xcode创建一个工程的多个taget,便于测试和发布多个版本

    背景:很多时候,我们需要在一个工程中创立多个target,也就是说我们希望同一份代码可以创建两个应用,放到模拟器或者真机上,或者是,我们平时有N多人合作开发,当测试的时候,在A这里装了一遍测A写的那块 ...

  2. Node.js学习笔记(6)——使用Express创建一个工程

    前提是搭建好了环境,node,npm,express:(推荐全局安装) 开始用express创建一个基础工程: express –t ejs microblog 进入文件夹之后 npm-install ...

  3. Xcode创建子工程以及工程依赖

    https://www.jianshu.com/p/f2bc7d155a86 阅读 7858 视频地址 如果文章不详细,点击看操作视频 项目需求:代码抽层,业务逻辑和数据处理要高度抽离,模块化,需要将 ...

  4. 使用IDEA创建一个SSM工程(非maven)

    说在前面的话 直到现在从Eclipse向IDEA转的人越来越多,但是IDEA的项目创建让人摸不清头脑,因此这里我创建一个非maven的ssm工程,供大家练练手,进一步的了解IDEA在项目中的使用. 创 ...

  5. windows下无法创建django工程的问题

    环境:python2.7  django1.7 安装好django后,将C:\Python27\Lib\site-packages\Django-1.7.7-py2.7.egg\django\bin; ...

  6. IOS开发之小实例--使用UIImagePickerController创建一个简单的相机应用程序

    前言:本篇博文是本人阅读国外的IOS Programming Tutorial的一篇入门文章的学习过程总结,难度不大,因为是入门.主要是入门UIImagePickerController这个控制器,那 ...

  7. 使用Express创建一个简单的示例

    1.安装Express 使用npm包安装工具来安装Express安装包,打开npm命令行,输入: npm install -g express 2.创建一个工程 本示例是在windows下创建的,项目 ...

  8. 用django创建一个简单的sns

    用django创建一个简单的sns 1.首先创建一个工程newsns django-admin.py startproject newsns 在工程目录下新建一个文件夹templates,在该文件夹下 ...

  9. Django命令行相关命令 以及创建一个空白网页的步骤

    django相关命令行命令: django.admin.py是Django的一个用于管理任务的命令行工具,manage.py是对django-admin.py的简单包装,每个Django Projec ...

随机推荐

  1. Android必知必会-使用okhttp的PUT方式上传文件

    注:如果移动端排版有问题,请看 简书版 (<-点击左边),希望CSDN能更好的支持移动端. 背景 公司的文件上传接口使用PUT协议,之前一直用的都是老项目中的上传类,现在项目中使用了okhttp ...

  2. Android简易实战教程--第十三话《短信备份和还原~三》

    之前写过短信备份的小案例,哪里仅仅是虚拟了几条短信信息.本篇封装一个业务类,且直接通过内容提供者,访问本系统的短信信息,再提供对外接口.如果想要短信备份和短信还原,直接复制这段代码即可.对于您调用这个 ...

  3. Android传感器概述-android学习之旅(七)

    传感器概述 传感器是第二代智能手机的重要标志之一.现在许多的手机和平板都内置了传感器(tv除外).android的SDK支持许多的传感器有十几种,但是手机只是支持一部分.例如方向传感器(电子罗盘)和重 ...

  4. Spark SQL官方文档阅读--待完善

    1,DataFrame是一个将数据格式化为列形式的分布式容器,类似于一个关系型数据库表. 编程入口:SQLContext 2,SQLContext由SparkContext对象创建 也可创建一个功能更 ...

  5. Linux多线程实践(8) --Posix条件变量解决生产者消费者问题

    Posix条件变量 int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr); int pthread_co ...

  6. Spring BeanFacoty doCreateBean方法分析

    上一篇,我们分析到了doCreateBean,现在继续: 先看看时序图 protected Object doCreateBean(final String beanName, final RootB ...

  7. Locally Weighted Linear Regression 局部加权线性回归-R实现

      局部加权线性回归  [转载时请注明来源]:http://www.cnblogs.com/runner-ljt/ Ljt 作为一个初学者,水平有限,欢迎交流指正. 线性回归容易出现过拟合或欠拟合的问 ...

  8. Leetcode_94_Binary Tree Inorder Traversal

    本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/42876657 Given a binary tree, r ...

  9. 算法学习笔记(一)C++排序函数、映射技巧与字典树

    1.头文件algorithm中有函数sort()用于排序,参数为:排序起始地址,排序结束地址,排序规则(返回bool型)例如,要将array[] = {5,7,1,2,9}升序排列,则使用: bool ...

  10. 网站开发进阶(二十二)HTML UI知识汇总(更新中...)

    HTML知识汇总(更新中...) 1.<iframe> 标签 浏览器支持 所有浏览器都支持 <iframe> 标签. 定义和用法 iframe 元素会创建包含另外一个文档的内联 ...