iOS Localization on a per target basis? - ios

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.

Related

Differentiate between iOS and macCatalyst in xcconfig file

In an xcconfig file it's possible to use sdk and arch specifiers. For example:
BUILD_SETTING_NAME[sdk=sdk] = value for specified sdk
BUILD_SETTING_NAME[arch=architecture] = value for specified architecture
How can I use this to use a different value when building for macCatalyst ("UIKit for Mac")?
OK, it turns out to be easier than I thought. You can simply do this in your xcconfig file:
SOME_PLATFORM_DEPENDENT_VALUE = "use this on iOS";
SOME_PLATFORM_DEPENDENT_VALUE[sdk=macosx*] = "use this on macOS including macCatalyst";
On the first line you set the value for all platforms. On the second line you set the value for a specific SDK. The specific value takes precedence over the "general" value.
That's it! You can learn more about these different options in this great NSHipster article.

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.

Setup different target for using different constant in Xcode

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

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.

Resources