Setup different target for using different constant in Xcode - ios

I know maybe a question is duplicated, but where I can check information. How to setup different targets to build with different bundle name etc.
Right now I know of course how to create different targets in Xcode, it is very simple to copy it from example from first target that was created automatically when I created project.
But I also have Constant.h and Constant.m files. I want to handle constants depend on which target I build for.
Let's say when build for target A I need to setup NSString const *toEmail = #"a#test.com", but in case if I build for the target B then toEmail = #"b#test";
Do I need to create two difference Constant files say ConstantA.m and ConstantB.m or maybe there is another best practice here. I don't want to recreate a wheel )

I setup Preprocessor Macro in target build settings for just one target. (For Example: TARGET_B)
And in code i check using
// Check if it's target B:
#if TARGET_B
NSString const *toEmail = #"b#test.com"
#else
NSString const *toEmail = #"a#test.com"
#end

Related

How can I differentiate between multiple targets in xcode at runtime

Working on an old objective c application where in I need to create multiple targets. Question is how do I differentiate between multiple targets run time in the code and accordingly I need to load the resources from bundle.
Project > Build Settings > Preprocessor Macros
define there different macros for different targets e.g.:
TARGET_1
TARGET_2
and in code you can diferenciate it like this:
NSString *pathToMyResource = nil;
#ifdef TARGET_1
pathToMyResource = #"pathToMyResourceForTarget1";
#else
pathToMyResource = #"pathToMyResourceForTarget2";
#endif
EDIT: added swift syntax
#if DEBUG
let apiKey = "KEY_A"
#else
let apiKey = "KEY_B"
#endif
see here: Swift 3: how to use PREPROCESSOR Flags (like `#if DEBUG`) to implement API keys?
You can use #matloob's answer. Below is an another approach.
You can also use Preprocessing for differentiating among targets.
Please have a look at following tutorial. This may also help you.
Reference :
Target Differentiation dynamically - Appcoda

iOS XCode: How to load a value from a user-defined setting from build settings at run time

I've got the following constant in the code:
static NSString* const MyUrl = #"www.myurl.com";
Is it possible at all to create a user-defined setting and assign a value which can replace the value of MyUrl const at run time or during archive?
My situation is the following: I have a project with various targets. Each target points to a different URL in the code. It would be great if I could manage the URL through a user-defined setting rather than having to change the code every time I change the target.
Consider using info.plist for storing such values.
No you could not change the value of const variable.
You can change the value of URL string by simply NSString *myURL = #"www.url.com";
and use the global variable in AppDelegate and use that from any where in project.
You can use pre processor macros for this purpose. Goto to Xcode>Project>Target>Build Settings>Preprocessor Macros. Then for every build configuration (Debug, release, etc) add a target specific macro. In your source code, you can now identify your target, by just referring to the macro using #ifdef.
Example:
#ifdef TARGET1
static NSString* const MyUrl = #"www.myurl.com";
#endif
#ifdef TARGET2
static NSString* const MyUrl = #"www.myur2.com";
#endif
The following image depicts the declaration of TARGET macro in build settings-
I think you need to use a database or any other source out of your app. And fetch the URL string whenever it changes and you can use your NSString variable inside the code. You can use parse for your need (However, Parse will stop their service next year but there are lots of free online DBs you can use). With this method you don't need to change your code to update URL strings. I hope I could get what you need correctly.

Assign a static constant at build time ios xcode

I should built and archive my application with Prod_URL and Stage_URL for our test team.
now i am using an Constant.h file and there is a code like;
//for stage
#define SERVICE_URL #"myStageUrl.com"
/*
//for prod
#define SERVICE_URL #"myProdUrl.com"
*/
And I always changing comment out lines to be able to build two different version of my app.
So now I wanna do it automatically.
I create two target like MyAppStage and MyAppProd. And I think I should write a Run Script for that to switch between these two #define lines. But I don't know how to write script.
Or are there any better way for that situation?
Thx,
If you have two separate targets you can place these defines in the project properties its self. To do that you go to your project properties. Click on the target you want to edit, click on the "Build Settings" tab and search for Preprocessor Macros. Define anything you want there and it will be visible for every class in that target.
Another option is to use the same Preprocessor Macros build setting and set a macro for STAGE. then in your Constant.h you can have something like:
//for stage
#ifdef STAGE
#define SERVICE_URL #"myStageUrl.com"
#else
//for prod
#define SERVICE_URL #"myProdUrl.com"
#endif
In your target for staging, add a preprocessor macro, something like STAGING_BUILD will do. Don't change the production target.
Now, in your code:
#ifdef STAGING_BUILD
//for stage
#define SERVICE_URL #"myStageUrl.com"
#else
//for prod
#define SERVICE_URL #"myProdUrl.com"
#endif
then only the required line will be compiled in based on the target selected to be built.

iOS: How to add conditionality based on Project Target

I am building a project that will eventually be compiled to make 4 slightly different applications. The main change I have to make are image changes, but I also want to change a few UILabels as well.
I know that I could create multiple XIB files and modify them to be attached to each target, but I would is there a way to use a macro #define if to detect the name of the target?
Example: Project: Project1
Targets: TargetA, TargetB
#define if Target = TargetA{
label.text = #"This is targetA";
}
Is this possible?
Thanks!
I found an easy way to do this... you can access the bundle identifier which is unique for each target:
NSLog(#"%#", [[NSBundle mainBundle] bundleIdentifier]);
C preprocess macro will accomplish this feature.
In Xcode:
TARGET->Build Settings->Preprocess Marcos
And your source code:
#if DEBUG
// debug build
#else
// release build
#endif
This is already defined macro. You can define your own macros in all project targets.

iOS Localization on a per target basis?

I have a single project which builds multiple Apps on a per target basis, in order to localize the Apps I can add localization languages to the project, but not on a per target basis. Meaning that any target we build will appear to support all localizations for the project. i.e. Target A must support English and French, but Target B must only support English.
Is there any way to add a localization language on a per target basis? Or is the correct way to do this, to branch the project and maintain different branches of the codebase with different localizations for different targets?
Let's try:
+ NSString* NSCustomLocalizedString( NSString *key , NSString *comment)
{
NSString *rs = nil;
#ifdef A //target A
//you define English-French
rs = NSLocalizedString(key,#"");
#else //target B
rs = NSLocalizedStringFromTable(key,#"Localizable.strings-en",nil);
return rs;
}
Select the localizable.strings files for the language you need to remove from a target.
Then remove the target membership for the selected files.

Resources