I am learning from the iOS 9 AppCoda book on Swift (https://www.appcoda.com/swift/) and I am stuck in particular on the Localization section. So the author has gone through with changing some user-facing strings in code from just String to NSLocalizedString. That makes sense and the changes I made there were automatically updated appropriately with the XLIFF file. In the section about Localisation, the author mentions that you can also translate Storyboard user-facing Strings with the Export Localization feature of Xcode.
Because it's a book you work through, he provides an already translated XLIFF file into Chinese and German which includes the source code translated text and the Storyboard elements translated as well.
When I import the files into Xcode, I see three storyboards (Base and the Chinese/German.strings, etc) but when I run the app, none of the Storyboard elements are actually translated and only the elements from the source code.
When I click on the German Storyboard, I get the "no localized strings".
The app in his example works and the UI elements in storyboard are translated but they're not in my case. The entire app thus far has been followed with the exercises so there aren't really any differences. Or even if there are, the similarities themselves should be translated, but in the Storyboard elements, they're not.
Does anyone have any ideas on why the Storyboard elements wouldn't be updated with the Translated text in my case?
Any thoughts would be appreciated.
Here is my guess... Exporting localization strings from Storyboards works a little different from exporting those strings from code.
The localization file for strings from code gets the actual text from the NSLocalizedString macro and creates a mapping such as:
"Original string" = "Translated string".
So, you just have to use "Original string" in your code then Xcode knows it should translate it to "Translated string".
However, the storyboard localisation file uses the UI objects handles to set localized strings. For example:
/* Class = "UILabel"; text = "Ops..."; ObjectID = "fe4-zT-gjU"; */
"fe4-zT-gjU.text" = "Wait for it...";
In this example my storyboard has a UILabel, with the text "Ops...", and that label has an ObjectID equal to "fe4-zT-gjU".
The object IDs are kinda unique for each object in each project, so obviously the object IDs from the app coda tutorial will be unique for the project the author created; unless you have downloaded the author's original storyboard, your storyboard will have all different object IDs, so Xcode won't know how to associate the correct translations to the correct objects.
I don't think Xcode will import localisation for objects with objectIDs it doesn't recognise.
So what I think you should do is to perform an "Export for localisation" operation. This should update your storyboard .strings file. Then you copy each translation from the tutorial file into your .strings file using an xliff editor. Boring, I know. Welcome to the app development world. :-)
When you added your localization did you select the storyboard file?
If so, then check that your scheme is set to the correct language. This can be done under Product > Scheme > Edit Scheme
If that doesn't do it, then check that your simulator is set to the language you want to display. This can be done in the simulator's settings, same as an iPhone.
Hope this helps.
Related
TLDR: Xcode generated storyboards for each language, however I want the "old"(?) *.strings files. How?
I am currently in the process of localising my storyboards. After I enabled everything, Xcode generated another storyboard alongside the original (english) one for me to localise. I was surprised, I expected a Localizable.strings file, like the apple documentation still states as of April 3, 2021:
For storyboard and XIB interfaces, select the user interface files (files with a .storyboard or .xib filename extension). Xcode adds a strings file to the localization folder that contains the text to translate, as well as comments that describe the user interface components. For example, if you add German to an iOS app that uses storyboards, LaunchScreen.storyboard becomes a group containing a LaunchScreen.storyboard (Base) and LaunchScreen.strings (German) file.
I searched around the internet, in apple developer forums, watched both WWDC18 and 19 talks about localisation in Xcode, but did not find a single mention of translated storyboards.
After the initial translation, which works great due to the simplicity of just filling everything in, it gets frustrating however, since every layout change needs to be repeated for every language. This can't be intended, there must be a better way, right? Sadly, I didn't find anything. Even a hint to a piece of documentation regarding these storyboard copies would be greatly appreciated. Thanks!
There are some screenshots of the possibility to convert these two formats via a dropdown, like the third picture in this post. However for me, there is no dropdown next to the language item when I click the storyboard, neither on the group, nor individual base or localised ones:
Is this a bug or am I missing something here? I am using macOS Big Sur 11.2.3 with Xcode 12.4 (12D4e).
Turns out, you need to use the Base Localization feature, the dropdown then appears and you can convert existing storyboards to *.strings files.
The problem my IOS app is facing is that all texts, titles, labels to be translated automatically in the Storyboard are not. At the same time, all texts, titles, labels to be translated by my Swift code, using NSLocalizableStrings are working well.
Here is my environment :
Xcode v 9.4.1
Development Language : English
Localization, English - 6 files localized
Development Language : French - 2 files localized (this line is below the other, correct ?)
Main.Storyboard includes:
Main.Storyboard (Base)
Main.strings (English), which contains all translations in English
The .strings files are correct and contains the translations for NSLocalizable functions
I have done Export for Localization to get an en.xliff file
In the file, it says source=fr and target=en, which is good
I have translated labels, titles, texts, etc in the en .xliff file
I have done Import for Localization using the en .xliff file
To test localization, I do Edit Scheme / Run, with Application Language set to English and Application Region set to System Region
What I see :
Whatever the view, all texts to be translated by a NSLocalizableString function in the Swift code are correctly translated and displayed as expected. Good
But, all texts to be translated automatically by the Storyboard are still displayed in French. All of them (View Title, Button, Label, etc). It looks like the Main.strings (English) is not read at all.
This last part is supposed to be straight forward, isn’t it ?
I have removed three times English and redo the full Localization process, with no effect.
My backup solution is to move all translations into the Swift code and not take advantage of the Storyboard automated translations, but honestly this is not exciting.
Any clue ? Any help ?
Many thanks
Problem:
If you create Localization StoryBoard. and after that you will add some label or button then That will not available in Localization storyboard.
Solution:
Delete complete Localization Story(< YourStoryBoardName >.String) from project. Don't remove only refrence.
Open en.lproj> < YourStoryBoardName >.String And Delete. Do this for other language also This Then again create this you will find all button and label in Localization
Important Note:
By deleting your All localization String will delete So do the backup
first.
In my iOS app, I am planning to let user to change the language.
What is the best approach to accomplish this?
Currently all my String is inside a struct. But I am wondering what is the best approach to change language according to what user choose.
Any suggestions?
The most common way to do this is not to allow the user to change the language within the app itself, but rather let iOS do this for you.
Here's a good tutorial to start localizing your app's strings using NSLocalizedString. You should follow the whole tutorial as it has a bunch of useful information about localization, but here's a brief overview of what you have to do:
Create a Localizable.strings file for your project. This file follows the format "Hello" = "Hello";, where the key on the left will be the string's identifier for NSLocalizableString and the value on the right is the localized string. In this case, you would replace any code references to this string (for example, #"Hello") with NSLocalizedString(#"Hello", nil).
Add your desired languages to your app's project (Project > [App name] > Localizations > "+" button). This will present a prompt containing your project's localizable files (strings files and storyboards) - you'll probably want to select all of them.
Select your Localizable.strings file, and in the Utilities (right side) menu, under Localization, click Localize. Select English as your starting language (assuming your app is currently in English).
You'll now have a list of your localizable languages with checkboxes. Enable each language, which will create a language-specific version of Localizable.strings.
All of your localized files, including Localizable.strings and your Storyboards, will now have a arrow in the Project Navigator. If you click these arrows to expand, you can edit each of your localizations for these files.
Done! Easy. You can test this in the Simulator or on your device by changing your device's language.
Once this has been completed, your app will load strings from whichever supported language the user has selected in their device settings.
This question also has some useful tips for localizing an existing app - in particular, mass-replacing existing strings with NSLocalizedString.
If you want to do your own solution then one of the many possible ways would be to:
Create your own singleton Localization Manager Class
Add every UILabel in the App into a dictionary which holds an UILabel and the key string. Then just:
for label in labels {
If let label = LocMan.sharedInst.labels["some Key"] {
label.text = NSLocalizedString("some Key" comment: "")
}
}
For other text classes you should do the same.
I exported the localization xliff file with no errors. I localized the file, imported back to Xcode and ran the app. Everything was good.
I exported the localization xliff file again for a second-round localization. I found many keys duplicated and they are not translated, of course. Why did this happen? Is it a bug in Xcode? How to work around it?
Side Note that might be helpful: I have test targets.
I noticed this issue the other day, I think it's due to translation not being able to differentiate between the localisations, often using localisation you can be lazy by typing something like:
NSLocalizedString(#"Blue", nil);
Using nil is valid but provides no information as to the context of the translation, if the string is more verbose and that string will only be used once then nil should be fine. In the above example though the context could have multiple meanings (colour, feelings, etc) so when writing localised code ensure that if it is used multiple times add a comment for the code and as long as its the same as another localised bit of text the translated strings should merge
Example
Creates 2 localised items
NSLocalizedString(#"Blue", #"Colour");
NSLocalizedString(#"Blue", #"Feeling");
Creates 2 localised items
NSLocalizedString(#"Blue", nil);
NSLocalizedString(#"Blue", nil);
Creates 1 localised item
NSLocalizedString(#"Blue", #"Colour");
NSLocalizedString(#"Blue", #"Colour");
As I expected, the Export XLIFF file includes localisation strings in test targets too. I am using Xcode 6.2 now and still there is no way to exclude test targets from this process.
I had to open the file using a text editor (for example, TextEdit) and remove all the localisation nodes for test targets.
I have the Storyboard, Base language and translated all the app into another language, so far it's working fine.
I would like to know, when I add new elements in the Storyboard that needs to be localized, how do you keep the strings file up to date.
I tried a suggestion, which is to switch this: to Interface Builder Cocoa Storyboard and then back to Localizable Strings, however the results are not good, most of the translation is lost and switched back to the Base language.
Is there a handy tool to regenerate and merge the strings in Storyboard? I tried few scripts but they always ended up wiping everything.
I've modified a skript that i've found here on stackoverflow to be able to also handle the localized strings in storyboards.
The skript only adds new key-value pairs to the .strings file, but keeps the ones that you have already translated.
You can get it from my github, for more details about my localization workflow read my blogpost