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.
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
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.
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
Solution is here: Multiple targets in Xcode.
You can create multiple targets for your app which is like
- MyApp-Dev
- 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.
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.
- Both Targets have Different AppIcon, so we can differentiate easily.
- Both have different Display Name (and, you can install both of them)
- 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’
By default, you will have a single target. In my case it is MultipleTragetsDemo
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
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:
- AppName-Dev
- 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
There you’ll find scheme name ‘MultipleTargetsDemo’. Click on it and select ‘Manage Schemes’
There you will have the scheme name depending upon the number of targets you have in your project.
Press ‘return’ key and rename it as Target name.
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
At Present, it’s out of project directory. Drag-n-Drop inside your project.
And, Next rename it as MultipleTargetsDemo-Prod.plist
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.
And, change the Info.plist File name
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.
Same with the Development target.
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.
We are half-done, let’s run the code.
Make sure you have chosen right scheme before running your code.
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,
For Production Target,
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.
And, rename it as AppIcon-Prod
Add different App Icon in both the asset file.
I’m using these two icon. S is for Development Target and P is for Production target.
|
After Adding Icon toiPhone App iOS 7-10 60pt move to Production Targets section.
And, choose AppIcon-Prod in App Icon Source.
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.
|
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
- While adding any file/resources to your project always choose both the targets you have in the project.
- 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