Your app is available around the world, but you’ve only made your app in the English language? You want to offer your app in the native language of ever user… but how?
Apple has 150 App Stores around the world with hundreds of millions of users. If your goal is to get as many downloads as possible, then make it available in every supported language (there are 40!!!). Maximize your apps potential via localization!
Localization is the ability of your app to display text, images, sounds, and numeric formats(dates and numbers), in the users device language. Localization should be standard practice in all apps, but prior to Xcode 6 it was quite a bit of work.
Apple has gone out of their way to simplify this process and after reading this demo I think you’ll be amazed. Xcode 6 makes localization a “pas sorcier”, or “no brainer”.
We typically create a text string object like this…
NSString *textString = @"My Text";
or
self.label.text = [NSString stringWithFormat:@"My Text"];
But this is only good for english and cannot be translated.
To add the power of localization to your text objects simply add the following:
self.label.text = NSLocalizedString(@"YOUR TEXT",@"A DESCRIPTION OF WHAT IT IS");
or
NSString *textString = [NSString localizedStringWithFormat:NSLocalizedString(@"YOUR TEXT", @"A DESCRIPTION OF WHAT IT IS")];
When this format is used, the first argument is the text string that the app will display, and the second argument is a text string which is a note to the translator providing a description of what is being translated. This is important for the translator to understand the context of what they are translating.
Let’s make a project to demonstrate.
Create a New Project…Single view application, iPhone, Objective-C.
Select Storyboard. Click the inspector pane and uncheck Use Class Sizes. This will create an “iPhone” looking view controller in the storyboard.
Drag on an a label, a text field, text view, and a label.
Control+Drag from the storyboard objects to the .h file and name your IBOutlets.
The .h file should look like the code below:
#import <UIKit/UIKit.h> @interface ViewController : UIViewController @property (weak, nonatomic) IBOutlet UILabel *label; @property (weak, nonatomic) IBOutlet UITextField *textField; @property (weak, nonatomic) IBOutlet UITextView *textView; @property (weak, nonatomic) IBOutlet UILabel *author; @end
In the implementation file, add text to the objects using NSLocalizedString. I’ll use a quote for this example.
The .m file
#import "ViewController.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. _label.text= NSLocalizedString(@"English", @"Language Label"); _textField.text = NSLocalizedString(@"Quote", @"Quote Word"); _textView.text = NSLocalizedString(@"It's choice - not chance - that determines your destiny.", @"Quote Body"); _author.text = NSLocalizedString(@"- Jean Nidetch", @"Author Name"); } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end
Build and Run in the simulator.
At this point your project should look like this:
Quit the simulator and select the project. Under the EDITOR menu select Add Localization.
Select the languages you will be translating to. This is done one language at a time. Once finished in the EDITOR menu select “Export For Localization…”
Xcode will create a folder containing individual files for each language you selected.
In this demo I have selected French, German, Hebrew, Italian, and Simplified Chinese. Okay, maybe a lot for a demo but… why not.
These files can then be sent to a translation service (recommended) or edited by you (not recommended).
The file is a standard XLIFF format file which has become an accepted standard for translation services to work with.
For a list of Apple recommended third party localization providers, visit the Apple Developer site at https://developer.apple.com/internationalization/#vendors.
The unedited translation file is an XML document. Here is a portion of the Italian file to be translated.
“SOURCE” is the original text in the label, text field, or text view.
“NOTE” Is the note for the translator so the translation can be in the correct context.
Between SOURCE and NOTE is where the translation will be placed as the TARGET.
This is NOT recommended. Translations should be completed by a certified translation service.
Language Label Quote Body
This is the same file edited.
Italian Language Label E 'la scelta - non casuale - che determina il tuo destino. Quote Body
Once your files have returned from the translation service, select your project, and under the EDITOR menu select “Import Localizations…”.
Import each language file one at a time. Once completed you can test in the Scheme editor. Product > Scheme > Edit Scheme. Under Application Language, select the language you want to test, then Build and Run in the simulator. You should see the text and labels display the translated text strings in the simulator.
What if you add another text field or image view after the translations have been done and imported? No problem! Just repeat the export process but this time you have an option to “include existing translations” Make sure that is selected. You’ll notice Xcode is exporting to the folder you created. I like to add ver2, or something to the file so that I don’t overwrite the original and I know there is a newer version. Click Save.
Your localized(translated) files will be exported with the existing translations as well as the new labels,field, or strings that needs translation. This way your translator can see what has been completed, and only worry about the additions.
To demonstrate how Xcode handles date formatting for different regions around the world, let’s add a date field and create a formatter. By using a date formatter Xcode will automatically adjust the date to be correct for the region.
Add a label to the view controller. Open the assistant editor. Control+Drag from the label to the .h file and name the UILabel dateLabel.
Xcode knows how to handle region specific number and date formats as long as the numbers and dates are passed through a formatter.
In the implementation file set up the date formatter.
-(NSDateFormatter *)dateFormatter{ static NSDateFormatter *dateFormatter = nil; if (dateFormatter == nil) { dateFormatter = [[NSDateFormatter alloc]init]; dateFormatter.dateStyle = NSDateFormatterMediumStyle; dateFormatter.timeStyle = NSDateFormatterShortStyle; } return dateFormatter; }
In viewDidLoad add a date to the date label using the formatter.
NSDate *date = [NSDate date]; self.dateLabel.text = [self.dateFormatter stringFromDate:date];
The complete .m file…
#import "ViewController.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. _textField.text = NSLocalizedString(@"Quote", @"Quote Word"); _textView.text = NSLocalizedString(@"It's choice - not chance - that determines your destiny.", @"Quote Body"); _author.text = NSLocalizedString(@"- Jean Nidetch", @"Author Name"); _label.text= NSLocalizedString(@"English", @"Language Label"); NSDate *date = [NSDate date]; self.dateLabel.text = [self.dateFormatter stringFromDate:date]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } -(NSDateFormatter *)dateFormatter{ static NSDateFormatter *dateFormatter = nil; if (dateFormatter == nil) { dateFormatter = [[NSDateFormatter alloc]init]; dateFormatter.dateStyle = NSDateFormatterMediumStyle; dateFormatter.timeStyle = NSDateFormatterShortStyle; } return dateFormatter; } @end
Return to the Scheme and try different language and region settings. This is just a primer to localization but it should get you off to a good start.
You can download the completed project here. localizeDemo
This is a screen shot running with French selected in the Scheme.
adauguet says
“Translations should be completed by a certified translation service.”
So, this would be better :-)
“C’est le choix – pas la chance – qui détermine votre destin.”
Martin says
Precisely! The translation used was by feeding the quote into google translate!
vanistrator says
Would you mind attaching the complete xliff files? The exported and the imported ones.
Thanks.
Dhananjay Patil says
Hi,
I am using xcode 6 and ios 8 am trying to run demo from the download link given in this tutorial, But its not working well, every time I changed device language it changes app name according to respective language but not other content, its remains in english. What should I do?