Multiple Targets in iOS

 

So, Why do you need Multiple Targets ?

I’m giving you an assumption. You have a project where you are interacting with Database using REST APIs. Needless to say, you will have a Login Screen, or Registration Screen or say you have Forgot Password Screen. Then, you must be having two databases Development_Db (for Development Users) and Production_Db (for Production Users).

It’s a common Software-Development approach, where we maintain a different database(s) as we don’t want to mix match development data (which developer/Tester do on their end) with production data (actual Live Users). It’s a healthy practice to maintain data in separate entity.

image14

And, I’m assuming you are maintaining two Web Service URL for development and production.

https://development.abc.com/v1/loginUser

https://production.abc.com/v1/loginUser

image08

You always had to keep an eye when you are releasing your build whether it’s a Development Build or Production Build before submitting to AppStore or Testers.

When you are releasing your build for Tester(s) then you have to target development Web Service URL and production Web Service URL when you are submitting to app store.

Here, you have two kinds of targets. One is Development (targeting to Tester/Developers) and Other is Production (targeting to AppStore).

Now, if I ask you achieve this you’ll code something like this.

let isDevelopment = true

// make it False when releasing build for App Store

  if isDevelopment {
      let API_PATH = "http://development.abc.com/v1/loginUser/"
  }
  else{
      let API_PATH = "http://production.abc.com/v1/loginUser/"
  }

 

You will maintain a boolean flag isDevlopment in your constant file. Make it true/false as per your need.

Now, I am assuming your Testers want to test both the development

and production build at the same on the same device.

image24

So, You have to tell them that,

“Dude, you can’t install both at the same time since, app has same bundle ID (or, package name) and you can’t have two apps with same Bundle ID ”

And, Tester is like,

“No I want to test both of them without uninstalling one”

And, you are like

image25

Solution is here: Multiple targets in Xcode.

You can create multiple targets for your app which is like

  1. MyApp-Dev
  2. MyApp-Prod

And, each Target has their own Info.plist file which meant you can maintain their different App Icon, Display Name, Bundle ID, their Version Number and frameworks.

image00

So, What we are going to do?

We are going to code a Demo app which will have two targets. One is Development and Other is Production.

  1. Both Targets have Different AppIcon, so we can differentiate easily.
  2. Both have different Display Name (and, you can install both of them)
  3. And, we will use different Web Service URL for different targets. So, you just have to choose target and your build will target to the kind of target you have chosen.

Demonstration

Step1.

Create a Single Page Application and just like you do for other Apps.

Say, I’ve named my project ‘MultipleTargetsDemo

image01

By default, you will have a single target. In my case it is MultipleTragetsDemo

image16

We want to duplicate the Target and with the same configuration. So, we right-click on it and choose Duplicate.

 

Next, press enter while selecting the Newly Created target and rename its name. Make it MultipleTargetsDemo-Prod

image17

It’s upon you to change the default target’s name. I personally change the target name as MultipleTargetsDemo-Dev. So, I follow a convention of having two targets:

  1. AppName-Dev
  2. AppName-Prod

 

But, for now you can ignore it. Assume, default target is for Development. And, other is Production target.

 

Step2.

Next, change the scheme name of newly created target. Make it as Target name.

So, focus your eye on Simulator Area

image02

There  you’ll find scheme name ‘MultipleTargetsDemo’. Click on it and select ‘Manage Schemes

image09

There you will have the scheme name depending upon the number of targets you have in your project.

image26

Press ‘return’ key and rename it as Target name.

image13

Step3.

Till now, you have created a target and changed the Scheme name. But, where is Info.plist file which I’ve told you earlier.

Check your Project’s File Navigator

image11

At Present, it’s out of project directory. Drag-n-Drop inside your project.

image15

And, Next rename it as MultipleTargetsDemo-Prod.plist

image23

It’s not the end. As, you’ve changed the plist file name. You have to specify this in your Build Settings. Choose Your newly created target  and move inside Build Settings > Packaging section.

image30

And, change the Info.plist File name

image20

From MultipleTargetsDemo copy-info.plist to MultipleTargetsDemo-Prod.plist

Step4.

Next, change the name of App for different Targets.

Select Target and change it’s Display name in General Section.

image28

Same with the Development target.

image07

And, You have to change the Bundle ID of the Production Target. As, we want both build targeting different target installed on same device.

 

Add -prod in last part of the Bundle ID of existing one.

image05

We are half-done, let’s run the code.

Make sure you have chosen right scheme before running your code.

image06

For time being, we have two Scheme. First is targeting to default target which is Development target. And, second is the Production Target.

Same, you have to follow in your real projects before generating Release Builds.

First, choose the default target which is a development and check in Simulator. And, next choose the Production Target  from schemes and run the code.

For Default Target,

image21

For Production Target,

image19

As you can see, we can install both the targets in same device. Reason is both the build sharing different bundle name.

Step5.

Next, we’ll add AppIcon for both the targets.

Navigate to Assets folder of your Project and add (+) a New AppIcon file.

image29

And, rename it as AppIcon-Prod

image03

Add different App Icon in both the asset file.

image12 image18

I’m using these two icon. S is for Development Target and P is for Production target.

‘S’ pointing to Staging. In Software Development, people use Staging and Development   interchangeably. So, don’t get afraid by this name. They are trying to Development = Staging.


After Adding Icon to
iPhone App iOS 7-10 60pt move to Production Targets section.

And, choose AppIcon-Prod in App Icon Source.

image04

Step6.

Next, we will add Custom Swift Flag in Custom Flag for Swift Compiler.

Choose the Default Target (for us it’s a Development Target) > Build Settings > Other Swift Flag > Debug > Add (+) -DDEVELOPMENT

It’s just like a PreProcessor flag which we can use it as a flag.

Note: Make sure your flag name should start with -D

image27


After Adding this flag, we will use this 
DEVELOPMENT  flag to determine whether your app is in DEBUG mode.

#if DEVELOPMENT

let API_PATH = "https://devlopement.abc.com/v1/”

#else

let API_PATH = "https://production.abc.com/v1/"

#endif

 

When you are using Development target (i.e MultipleTargetsDemo) then it will pick the https://devlopment.abc.com/v1 as there is DEVELOPMENT flag in the custom flag.
#if, #endif and #else preprocessor macro which we are using to access preprocessor flags. This is the standard way to access Swift Custom Flag.

In production target, it will use https://production.abc.com/v1 as there is no DEVELOPMENT flag.

You should take Care of

  1. While adding any file/resources to your project always choose both the targets you have in the project.
  2. If you are using CocoaPods, then you must specify link_with property in your podFile.
source 'https://github.com/CocoaPods/Specs.git'

platform :ios, '7.0'

workspace 'todo'

link_with ‘MultipleTargetDemo’, 'MultipleTargetDemo-Prod
pod 'Alamofire'

Always create multiple targets in your app when you are using for Development, Production, Beta Version, Pro Edition of Your App. As, it will help you to separate code from one-another.Conclusion

Leave a Reply