Reputation: 1490
What are your best practices regarding Localization for iOS? I have been working quite a lot with Localization but it feels like is not good enough and scalable. There needs to be some better way. This is my current approach:
I have tried to create a xliff file from Xcode, but never got it to work. It always fails to export the file.
Error msg: Failed to read strings file ./..../Localizable.strings/ The data couldn’t be read because it isn’t in the correct format.
So.. How do you deal with Localizedstrings in iOS? Especially. What are your approaches around localizating storyboard files? I've seen people setting all the localizedstrings in code. But it feels like a unnecessary step to create a lot of IBOutlets
for that cause.
Upvotes: 10
Views: 3558
Reputation: 4684
.strings
and .stringsdict
are indeed working well. I don't fancy any of the storyboard translation approaches, they're IMHO too fragile and it sucks having to complete the whole cycle again just because you added/removed/or changed anythingin the storyboard.
I have good results with the following approach:
.strings
localization keys for titles/subtitles/placeholder/texts in your storyboard entities.UIViewController
baseclass (or a category) that traverses your UI and sets the localizations on supported widgets using your keys in the storyboard.I call the helper function in my viewDidLoad
. Here is an example of it:
static void translateLocalizableStringsInView( UIView* v )
{
NSBundle* mainBundle = [NSBundle mainBundle];
UIView* view = v;
if ( [view isKindOfClass:UILabel.class] )
{
UILabel* label = (UILabel*)view;
if ( label.text.length )
{
NSString* localizedString = [mainBundle localizedStringForKey:label.text value:nil table:nil];
if ( localizedString.length )
{
label.text = localizedString;
}
}
}
else if ( [view isKindOfClass:UITextField.class] )
{
UITextField* textField = (UITextField*)view;
if ( textField.text.length )
{
NSString* localizedString = [mainBundle localizedStringForKey:textField.text value:nil table:nil];
if ( localizedString.length )
{
textField.text = localizedString;
}
}
if ( textField.placeholder.length )
{
NSString* localizedString = [mainBundle localizedStringForKey:textField.placeholder value:nil table:nil];
if ( localizedString.length )
{
textField.placeholder = localizedString;
}
}
}
else if ( [view isKindOfClass:UIButton.class] )
{
UIButton* button = (UIButton*)view;
NSString* title = [button titleForState:UIControlStateNormal];
if ( title.length )
{
NSString* localizedString = [mainBundle localizedStringForKey:title value:nil table:nil];
if ( localizedString.length )
{
[button setTitle:localizedString forState:UIControlStateNormal];
}
}
}
else if ( [view isKindOfClass:UISegmentedControl.class] )
{
UISegmentedControl* sc = (UISegmentedControl*)view;
for ( NSUInteger i = 0; i < sc.numberOfSegments; ++i )
{
NSString* title = [sc titleForSegmentAtIndex:i];
if ( title.length )
{
NSString* localizedString = [mainBundle localizedStringForKey:title value:nil table:nil];
if ( localizedString.length )
{
[sc setTitle:localizedString forSegmentAtIndex:i];
}
}
}
}
}
@implementation UIViewController (LocalizableStrings)
-(void)LT_translateLocalizableStringsInView
{
[self.view LT_iterateThroughAllSubviewsRecursively:YES usingBlock:^(UIView * _Nonnull view, BOOL * _Nonnull stop) {
translateLocalizableStringsInView( view );
}];
if ( self.navigationItem.titleView )
{
translateLocalizableStringsInView( self.navigationItem.titleView );
}
}
Upvotes: 2
Reputation: 5640
Use the export/import XLIFF feature that's available since Xcode 6. It's a universal file format known by most translation tools and Xcode takes care of keeping everything in sync for you. There are also sessions from WWDC 2014 that go into some detail about this.
Make sure your storyboards are in Base.lproj (this is the default for new projects) and that you're using auto layout with localization-friendly constraints (which is necessary so that the layout properly adjusts for different-length translations).
Upvotes: 1
Reputation: 11597
What i did which is quite a mission initially, but worth it in the long run, is to put all your translations in an excel file, then save out your excel doc as a csv. Then i wrote a little parser that will spit out the csv file into the strings file format. Good for keeping strings aligned if you have an android project as well.
Upvotes: 2