Localization of a programming language without rebooting

I want to create an application for iPhone with English and Arabic. I checked the internationalization document for the language switch, however, for this to happen, I need to manually go and change the iPhone settings. I do not want to do this. So what I plan on the main screen, I will have two buttons in English and Arabic. If the user clicks Arabic, I will have Arabic text, and if the user selects English, the application will be in English.

Any idea / suggestion on how to do this?

Note. I do not want to manually switch and change the language.


Change 1

According to @Jano, I did below.

A new project has been created. Added Arabic language in localization. Now I have two storyboards and two InfoPlist.strings files.

Added the file Localization.h and .m, as shown in the answer.

Directory structure MyProject-ar.lproj and MyProject-en.lproj

Contents Plist "myButton01" = "Back"; and "myButton01" = "ظهر";

The first view controller has two buttons in English and Arabic. The action on this button is called up.

 - (IBAction)pressedEnglish:(id)sender { [Localization sharedInstance].fallbackLanguage = @"ar"; [Localization sharedInstance].preferredLanguage = @"en"; NSLog(@"pressed english"); } - (IBAction)pressedArabic:(id)sender { [Localization sharedInstance].fallbackLanguage = @"en"; [Localization sharedInstance].preferredLanguage = @"ar"; NSLog(@"pressed arabic"); } 

In the second controller, I added one button and gave the name myButton . Now in viewDidLoad I have

[self.myButton setTitle:localize(@"myButton01") forState:UIControlStateNormal];

I hope this should work, however, when I start the project, I see the button myButton01

Any reason this is happening?


Edit 2

I have a problem with Edit 1 . I renamed InfoPlist.strings to Localizable.strings and it worked. But but, but I still get the Arabic text no matter which button I click.

When I discovered the reason, I discovered that it was because of the statement below that we have in Localization.m

 static Localization *shared = nil; dispatch_once(&pred, ^{ shared = [[Localization alloc] init]; shared.fallbackLanguage = @"en"; shared.preferredLanguage = @"ar"; 

The problem, finally, is in two lines. Since we set Arabic as preferredLanguage, I always see Arabic text.

What changes do I need to make so that I can change it as a button click.

+1
ios objective-c internationalization
source share
1 answer

You want to set the application language from the application user interface, ignoring user preferences on the device. This is unusual, but here you go ...

First write all your language strings in the directory structure as follows:

 i18n/en.lproj/Localizable.strings i18n/ar.lproj/Localizable.strings 

Create an additional directory with the appropriate two-letter code for each supported language.

If files are recognized as i18n resources, they will be represented as follows: enter image description here

Files will have a key = value with the following format:

 "button.back" = "ظهر"; 

In the code, replace any localizable string with the key. Example:

 [self.stateBtn setTitle:localize(@"button.back") forState:UIControlStateNormal]; 

Usually you use NSLocalizedString(@"key",@"fallback") , but since you want to ignore the iPhone settings, I wrote a localize(@"key") macro localize(@"key") , which will have the following implementation:

Localization.h

 #ifndef localize #define localize(key) [[Localization sharedInstance] localizedStringForKey:key] #endif @interface Localization : NSObject @property (nonatomic, retain) NSBundle* fallbackBundle; @property (nonatomic, retain) NSBundle* preferredBundle; @property (nonatomic, copy) NSString* fallbackLanguage; @property (nonatomic, copy) NSString* preferredLanguage; -(NSString*) localizedStringForKey:(NSString*)key; -(NSString*) pathForFilename:(NSString*)filename type:(NSString*)type; +(Localization*)sharedInstance; @end 

Localization.m

 #import "Localization.h" @implementation Localization +(Localization *)sharedInstance { static dispatch_once_t pred; static Localization *shared = nil; dispatch_once(&pred, ^{ shared = [[Localization alloc] init]; [shared setPreferred:@"en" fallback:@"ar"]; }); return shared; } -(void) setPreferred:(NSString*)preferred fallback:(NSString*)fallback { self.fallbackLanguage = fallback; self.preferredLanguage = preferred; NSString *bundlePath = [[NSBundle mainBundle] pathForResource:@"Localizable" ofType:@"strings" inDirectory:nil forLocalization:self.fallbackLanguage]; self.fallbackBundle = [[NSBundle alloc] initWithPath:[bundlePath stringByDeletingLastPathComponent]]; bundlePath = [[NSBundle mainBundle] pathForResource:@"Localizable" ofType:@"strings" inDirectory:nil forLocalization:self.preferredLanguage]; self.preferredBundle = [[NSBundle alloc] initWithPath:[bundlePath stringByDeletingLastPathComponent]]; } -(NSString*) pathForFilename:(NSString*)filename type:(NSString*)type { NSString *path = [self.preferredBundle pathForResource:filename ofType:type inDirectory:nil forLocalization:self.preferredLanguage]; if (!path) path = [self.fallbackBundle pathForResource:filename ofType:type inDirectory:nil forLocalization:self.fallbackLanguage]; if (!path) NSLog(@"Missing file: %@.%@", filename, type); return path; } -(NSString*) localizedStringForKey:(NSString*)key { NSString* result = nil; if (_preferredBundle!=nil) { result = [_preferredBundle localizedStringForKey:key value:nil table:nil]; } if (result == nil) { result = [_fallbackBundle localizedStringForKey:key value:nil table:nil]; } if (result == nil) { result = key; } return result; } @end 

This will use the search for key lines in the Arabic file, and if the key is missing, it will look in the Arabic file. If you want it in another way, do the following from the button handlers:

 [[Localization sharedInstance] setPreferred:@"ar" fallback:@"en"]; 

Sample project on Github .

If localization does not work

If localization does not work, use the plutil command-line tool to check the file format. It should output: Localizable.strings: OK . Example:

 $ plutil -lint Localizable.strings Localizable.strings: OK 

This format is described in Internationalization Programming Topics> String Localization . You can add comments // single-line or /* multi-line */ . For non-Latin languages, it is recommended to code Localized.strings in UTF-16. You can convert between encodings in the Xcode inspector panel.

If it still doesn’t work, check that you copy the Localizable.strings file in the “Copy Files” phase of your target. Note that when you add Localizable.strings files there, sometimes they appear in red, continue to do this until the file appears in black, and then delete the red ones (hacky, I know, Xcode is to blame).

copy files

+4
source share

All Articles