多target来构建大量相似App

来源:互联网 发布:中山门淘宝街怎么走 编辑:程序博客网 时间:2024/04/27 22:12

问题描述:(主要有以下两个场景)

1、新开始的项目大概是这样的:做行业app,行业包括但不限于旅游、交通、餐饮、教育等。所有的行业app会出现基本相同的注册和登录以及首页逻辑和界面(只是背景图片不一样而已),基本相同的页面风格,基本相同的个人空间、基本相同的服务器交互协议等等。不同点包括:应用图标,启动画面,应用启动后的首页、大部分数据的展示方式和逻辑跳转。

2、在一个已经发布app的基础上衍生出一个类似的应用,大部分逻辑和功能相同,而且后续还会不会再有这样的app出现不确定。

无论是场景1还是场景2,我们都会考虑是新建工程创建app(将相同的代码从原工程中拷出来)还是其他的方式?首先个人觉得新建工程是一个很不好而且是一个很没有水平的办法,假如以后在原来的app上发现并解决了某些bug,还得记得把出现同样代码的所有app都改过来,并提交测试,所以选择了多target的方式,以下具体介绍:

技术解决方案:

1、抽取所有应用所公用的代码,做成公共模块(公共模块将成为所有target的公共编译源代码)

2、为不同应用创建各自的target,为不同的target添加各自的资源文件、源代码和所依赖的库文件

3、编译不同应用选择各自的target。

target是什么?

先简单介绍一下Xcode中target的概念,苹果在文档中写道:

Targets that define the products to build. A target organizes the files and instructions needed to build a product into a sequence of build actions that can be taken.”

简单的理解的话, 可以认为一个target对应一个新的product(基于同一份代码的情况下). 但都一份代码了, 弄个新product做啥呢? 折腾这个有意思么?
其实这不是单纯的瞎折腾, 虽然代码是同一份, 但编译设置(比如编译条件), 以及包含的资源文件却可以有很大的差别. 于是即使同一份代码, 产出的product也可能大不相同.
我们来举几个典型的应用多Targets的情况吧, 比如完整版和lite版; 比如同一个游戏的20关, 30关, 50关版; 再或者比如同一个游戏换些资源和名字就当新游戏卖等等。

targets之间什么相同,什么不同

既然是利用同一份代码产出不同的product, 那么到底不同Target之间存在着什么样的差异呢?
要解释这个问题, 我们就要来看看一个Target指定了哪些内容.

从XCode左侧的列表中, 我们可以看到一个Target包含了Copy Bundle Resources, Compile Sources, Link Binary With Libraries. 其中
Copy Bundle Resources 是指生成的product的.app内将包含哪些资源文件
Compile Sources 是指将有哪些源代码被编译
Link Binary With Libraries 是指编译过程中会引用哪些库文件。

通过Copy Bundle Resources中内容的不同设置, 我们可以让不同的product包含不同的资源, 包括程序的主图标等, 而不是把XCode的工程中列出的资源一股脑的包含进去.
而这还不是一个target所指定的全部内容. 每个target可以使用一个独立, 不同的Info.plist文件.  
我们都知道, 这个Info.plist文件内定义了一个iPhone项目的很多关键性内容, 比如程序名称, 最终生成product的全局唯一id等等.
而且不同的target还可以定义完整的差异化的编译设置, 从简单的调整优化选项, 到增加条件编译所使用的编译条件, 以至于所使用的base SDK都可以差异化指定.

创建第二个target

除了系统默认的target,我们再为产品新建一个target。

创建target有多种方法, 我们可以从现有的target(Duplicate)上复制出一份, 然后略加改动, 也可以完全新建一个target出来. 但其实说穿了, 两个方法大同小异
1、利用复制的方法创建target:

在现有的target上, 右键选择 "Duplicate", 或者选中现有target后, 在顶部菜单的Edit内选择"Duplicate"也可以.
此时我们就得到了一个新的target,  这个新的target与原有的target是完全一致的, 余下的就是一些差异化的修改, 这个我们后面再说

2、创建全新的target

点击Add Target后, 首先会让你选择target的类型, 既然我一直所指的都是程序本身, 那么自然选择Application了(至于其他的嘛, 有兴趣的自己研究吧, 比如我们可以把程序中的部分提取成一个Static Library).  Next后, 会让你输入一个新的Target的名字, 而不像复制的方法中, 默认生成 xxxxx copy这样的target名.
但是这样生成出的Target几乎是空的. Copy Bundle Resources, Compile Sources, Link Binary With Libraries里面都没有任何内容. 编译设置也是完全原始的状态.
可以通过拖拽内容到这些target的设置中, 以及调整编译选项来完成Target的配置.

target中部分内容的修改

其实这段的部分内容, 在非多Targets的工程中也可能会用得到.
由于修改基本都是在工程/编译设置中完成, 因此没有特殊情况, 就不再声明了, 打开target对应的工程/编译设置的方法可以采用选中要修改的target, 点击build settings来做到.
生成的product名称的修改: Packing段内的Product Name一项
Info.plist文件名: Packing段内的Info.plist File一项, 比如复制出来的target觉得那个xxxxx copy.plist太傻就可以在这里改
条件编译: 增加一个User-Defined Setting(Target "xxxx" Info的build页的左下角那个齿轮中可以看到这个内容), 在Other C Flag里面填入, 比如要定义一个叫做LITE_VERSION的define值, 我们可以写上 "-DLITE_VERSION" 或 "-DLITE_VERSION=1". 那么在程序中就可以用
    #if defined(LITE_VERSION)
    #else
    #endif 这样的条件编译来部分差异化代码了
也许有些朋友记得我在代码区贴过的检测破解版的代码, 其中有一种检测方法就是看info.plist是文本还是二进制的, 那么我们能否建议一个模拟破解的target, 直接生成文本的info.plist以便测试呢? 当然可以, 在packing段内, 有一项叫"Info.plist Output Encoding", 默认值是Binary, 我们只要选成xml, 那么生成出的product.app内的info.plist就直接是文本样式的了.
另外, 向Copy Bundle Resources, Compile Sources, Link Binary With Libraries内添加/删除文件, 可以在要改动的文件上, 选择get info, 并且切换到Target页, 勾选要引用这个文件的target即可. 比如icon.png可以指定给默认target, 而icon_lite.png指定给lite verion的target。

0 0
原创粉丝点击