原文:http://www.codza.com/free-iphone-app-version-from-the-same-xcode-project

There are more than 15,000 apps in the app store and hundreds are added daily. You need a way to show off your awesome creation to the millions of potential buyers.

One of the most effective marketing tools for small fish is releasing a free version of the app. To do that, you could copy the whole project, but then you would be duplicating code, maintaining it in two places and what if there’s an update?

In this post I’ll show you a better way: building two versions of your app from the same xcode project using targets and some other magic. Source code for the sample project is available here:twoForOne.

I’ve built a very simple app, it displays an image in UIImageView and has two buttons. Looks like this:



This is the pay-for version. The free version will have a different image (blue) and the expensive button will be hidden. This will demonstrate how to use a different set of resources (red image vs blue image) and how to modify code (hide button) at compile time based on which target is active.

First we’ll add a new build phase to the target. This will allow us to modify the background and icon resources later. It’s easier to add it now because we only need to do it for one target (it will be automatically duplicated with the target.) Right click on the target and select Add / New Build Phase /New Run Script Build Phase (you can click on the screen shot to see it better).

Type ./targetSetup in the script window. targetSetup is the script that does the work; we’ll create it later.

Take the Run Script build phase and move it to the top of the stack. We want this to run before any other build phase.



Now duplicate the target and name the new target twoForOneFree (right click on the target and select duplicate). (If you don’t have a right button on your mouse, go and get one. Those stupid soap bar mice are so not cool anymore… were they ever?):

Notice that xcode made a duplicate of the Info.plist file:



Info copy.plist is not a very nice name, so rename it to InfoFree.plist. You also have to tell the target to use the renamed plist, so open the info window for thetwoForOneFree target (right click on the target and choose get info- you see how much nicer it is that you have a right mouse button?), make sure that you are looking atAll Configurations andAll Settings and typeinfo into the search box. Change theInfo.plist file setting to point atInfoFree.plist:



In the same info window change the product name to twoForOneFree (this will be the name of the .app and by default this is what the iphone will display under the icon.) Typeproduct name in the search box to find the setting quickly:

The compiler doesn’t know which target is active, so we’ll define a directive that will be easy to use in code to create version specific modifications (this is what we’ll use to hide the expensive button). Still in the same window, search forother c. If you find a key called Other C Flags, you are in luck: set it to-DTWOFORONEFREEand skip the next paragraph.

If not, you need to create one. At the bottom of the window click the settings (gears) button and selectAdd User-Defined Setting and typeOTHER_CFLAGS for the key and-DTWOFORONEFREE for the value:

This instructs the compiler to define the TWOFORONEFREE macro for this target.

Look at lines 18-20 intwoForOneAppDelegate.m. We use an #ifdef directive to hide the expensive button if this macro is defined:

#ifdef TWOFORONEFREE
[expensiveButton setHidden:YES];
#endif

Obviously you;ll need to do more than hiding a button. You can use this same approach to do other modifications to the free version. You can also define aTWOFORONEmacro on thetwoForOne target for more flexibility (you can use that macro to add features that the free version doesn’t have.)

Now we’ll look at modifying resources. We want the free version to have a different bacground and also a different icon. I created two versions of the background, you can see them in theImages folder:



The UIImageView uses bg.png. The other two files, bg_red.png andbg_blue.png are not added to the xcode project (you can add them, but it’s not necessary). I want to copybg_red.png tobg.png when building the expensive version andbg_blue.png tobg.png for the free build.

Similarly, there is a Icon_red.png and Icon_blue.png at the project level, one of those will be copied toIcon.png to get the correct icon.

We already added the run script build phase that calls the targetSetup script. Now let’s create s shell script. Right click onResources(so much milage out of that new right mouse button!) and selectAdd / New File. From the dialog select theOther category (all the way at the bottom) and then theShell Script type:

In the next dialog enter targetSetup for the name and uncheck both targets (we don’t want this script to be copied into any of the targets at build time):

The script itself is very simple. It copies the correct bg file and Icon file based on the selected target (the build process conveniently sets an environment variable with the target name).

#!/bin/tcsh -f

echo .targetSetup: $TARGET_NAME

if ($TARGET_NAME == “twoForOne”) then
cp Icon_red.png Icon.png
cp Images/bg_red.png Images/bg.png
endif

if ($TARGET_NAME == “twoForOneFree”) then
cp Icon_blue.png Icon.png
cp Images/bg_blue.png Images/bg.png
endif

#

That’s it! Just set the desired target and you can build the expensive or free version from the same project:

Here are some screenshots. You can see that even the icons are different (as expected):



You can download the twoForOne xcode project
here

xcode多target的更多相关文章

  1. [Xcode]使用target进行协同开发

    协同开发时候发现难免会因为某些条件宏导致上传到SVN的代码影响到其他同时,但是每一次去修很多条件编译也不是很方便,所以可以通过新建自己的target来控制product. 一.创建自己的target: ...

  2. xcode 添加target

  3. [转]Jenkins Xcode打包ipa

    本地打包. 如果Mac 上没有安装brew.先安装:ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/ins ...

  4. Xcode entitlement 问题定位和解决指南

    背景故事 前两天,本来一个运行正常.打包测试都没问题的XCode工程突然爆出各种奇怪的Entitlement错误: 什么签名的内容跟配置文件的不一致. 又或者 无法安装,因为签名或者配置文件的配置错误 ...

  5. 【转】xcode APP 打包以及提交apple审核详细流程(新版本更新提交审核)

    原文网址:http://blog.csdn.net/mad1989/article/details/8167529 最近项目到了最后的阶段,测试完一切ok后,准备打包以及提交,不料看到网上众教程,好多 ...

  6. xcode APP 打包以及提交apple审核详细流程(新版本更新提交审核)

    链接地址:http://blog.csdn.net/mad1989/article/details/8167529 打包发布APP流程真机测试和APP发布流程APP提交审核流程真机测试打包发布上传出错 ...

  7. Jenkins 集成Unity3D Xcode

    如果Mac 上没有安装brew.先安装:ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)& ...

  8. Jenkins Xcode打包ipa

    本地打包. 如果Mac 上没有安装brew.先安装:ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/ins ...

  9. 使用多target来构建大量相似App

    转自 come from : http://devtang.com/blog/2013/10/17/the-tech-detail-of-ape-client-1/ 猿题库iOS客户端的技术细节(一) ...

随机推荐

  1. Delphi中运行时改变panel的位置及大小(通过wm_SysCommand来实现)

    procedure TForm1.pnl1MouseDown(Sender: TObject; Button: TMouseButton;  Shift: TShiftState; X, Y: Int ...

  2. JAVA之File类创建对象构造函数传参数需要注意的几点

    java中File类用于创建一个文件对象. 首先看一段代码: 1. package MyText1; import java.io.File; public class MyText1 { publi ...

  3. Android开发:在onTouchEvent中处理任意时间的长按事件

    Android提供了GestureDetector类来处理一些常用的手势操作,比如说 onLongPress,onFling 等.但这里不使用GestureDetector,而是直接在自定义View重 ...

  4. 如何将自定义标签封装成一个Jar包

    当我们在一个web应用中开发好一些自定义标签的时候,这些自定义标签通常有标签处理器Java类,和一个描述这些标签tld文件,如果我们想在以后别的web工程中还能用上这些标签,可以将这些自定义标签封装在 ...

  5. (Relax 数论1.6)POJ 1061 青蛙的约会(扩展的欧几里得公式)

    /* * POJ_1061.cpp * * Created on: 2013年11月19日 * Author: Administrator */ #include <iostream> # ...

  6. Net Core-Razor

    几行代码解决Razor中的嵌套if语句 MVC开发中,经常会遇到在razor中插入简单的逻辑判断. @if (clientManager.IsAdmin) { if (!Model.Topic.Top ...

  7. PHP之操作数据库

    数据库,顾名思义,是一个存放数据的容器.然后在使用过程中对数据库里面的数据增删改查,具体是怎么实现的呢? 这儿不得不提一下一个神奇的东西:SQL语句:结构化查询语言(Structured Query ...

  8. jquery控制动态生成的gridview中多列checkbox的全选反选及自动判断是否全选状态

    动态生成的Gridview的前台html代码如下:     <table class="usertableborder" cellspacing="0" ...

  9. Visual Studio Code中文文档

    Visual Studio Code中文文档 Visual Studio Code是一个轻量级但是十分强大的源代码编辑器,重要的是它在Windows, OS X 和Linux操作系统的桌面上均可运行. ...

  10. rsync Backups for Windows

    Transfer your Windows Backups to an rsync server over SSH rsync.net provides cloud storage for offsi ...