I appreciate your help in advance. I have searched high and low for an answer with no luck.
I have an app that uses very specialized sports terms which I store in a plist file. Those terms are then displayed in a UITableView. When the user taps on the skill, a video demo is played. The app works great, but I would very much like to localize it for other languages.
I have gotten the terms translated, and I was hoping I could localize the plist file by making a copy of it and just changing the sport-specific terms in each successive copy of the file, and then put it in its respective language folder. Is this possible and if so, can someone please point me to a good example or tutorial?
So far, I have I have tried to localize the plist file for Russian in Xcode and put it in its own ru.lproj folder, however, then when I run it in the simulator no data appears at all in the UITableView! Without the Russian file, it works fine. So my thought is that somehow Xcode is confusing the plist file because the name is the same, even though it is in a different directory (en.lproj and ru.lproj). The file is called Basic.plist in both directories. This process is totally confusing to me, and from what I gather it shouldn't be that difficult to figure out!
Again, thank you in advance. The localization concept is completely new to me and I am eager to learn it. I am quite sure I understand how the .strings files work with strings that are embedded in code, but I would like to know if it is possible to translate an entire pList file.
A lot of things could be wrong. One possibility is that the plist files don't get copied into the bundle (verify in your target's Build Phases page--it should say Basic.plist with "...in (localization).lproj" written next to it.
If you have manually created the ru.lproj, maybe you copied it in the wrong place, or left the original file in the wrong place (it should now be inside en.lproj). Rather than manually create the file, it's easiest to select the file Basic.plist in XCode and use the Localization control inside File Inspector to add localizations. As Kevin Grant mentions, if this doesn't show your file as having English and Russian, then something is wrong, and you could start again using the + control.
Finally, I'm not 100% sure about this but close enough: I believe your code probably needs to be updated to figure out where to load the plist file from. It it were a .xib or a .strings file, you wouldn't have to do this as this would be automatic and iOS knows to look inside the relevant .lproj folder first (when you load a .xib you only specify its name, not its exact location). But I assume you are loading the plist file through a specific path, therefore the path must now include the .proj folder.
If possible for you, I think a nicer approach to having different plist files per language would be to have just one plist, but instead of displaying the string from the plist you could use it as a key to your .strings file. You can retrieve the localization using the NSLocalizedString macro (which is defined as [[NSBundle mainBundle] localizedStringForKey:(key) value:#"" table:nil]) which will give you the corresponding value in the localized .strings file at run time. Of course this would mean that when you update your plist, you would also have to update your .strings files to match. The good thing is that you wouldn't need to determine the path of the plist for your active language -- with NSLocalizedString, you don't provide a path at all.
Related
I'm attempting to add localizations to values that appear in my Info.plist file. I'm having no trouble doing this for top-level keys using an InfoPlist.strings file. But, I cannot figure out how to get it to work for non-top-level values.
For example, the CFBundleDocumentTypes is an array of dictionaries. I need to localize each array's CFBundleTypeName key differently. A similar situation exists for UTExportedTypeDeclarations/UTImportedTypeDeclarations, with the UTTypeDescription key.
Apple's documentation on UTTypeDescription specifically says that it can be localized with an InfoPlist.strings files. And I've tried, but have not been successful.
As reference, I tried to refer to Apple's own apps. The only one I was able to find that uses any non-root keys was Xcode, and Xcode isn't actually localized to anything other than English. I cannot be sure if its approach actually works. And, there's at least some strangeness within Xcode's bundle, because there are keys that appear in its InfoPlist.strings file that aren't actually in the Info.plist itself.
Does anyone know how (or if) this can be done?
Real life example with my own app. If you have an exported type with this:
<key>UTTypeDescription</key>
<string>CreaPhoto document</string>
My French translation in InfoPlist.strings is:
"CreaPhoto document" = "Document CréaPhoto";
It seems so dumb a "duh yeah of course" moment, but this is totally different from everything else in the info.plist translations, where you are expected to put the key when it's in root. No donut to Apple for not explaining this in their page.
Things to add in macOS: you must increment your Bundle ID each time you modify this (38 to 39 to 40 to 41 to 42 ...), you must build your new version, execute it in debugger (or release), and you must logout and logon so it gets taken into account.
There are ways with less steps, but this is the safest sure-fire way I found to get it applied in Finder.
I have this project localized in several languages. Xcode shows the following list of files:
You can see that some languages have more files than others. Is there a way to list what files are missing on each language?
Yes, I know that I can use the parameter -NSShowNonLocalizedStrings YES as an argument passed on launch. I did that but that is not showing anything.
This is an indirect answer to your question; If you have that many .strings files you might want to organise them more structurally.
You could put all translatable strings in either a database or a spreadsheet and generate your source files from there. This may sound like more work but I think in the end it saves time.
See this other question about consolidating strings files. Or see my example spreadsheet to manage your localisations and spot missing texts more easily.
I'm currently developing an application for IOS and I have four Localizable.strings files, each representing a different language. The thing is, i want to be able change the file that is being used without having to restart the application.
You can't do it without restarting the App.
A work around is store the language and it's values in a database file or in a plist file. Then use the data from there. (Basically it is not a good idea)
I have read a few tutorials about iOS's tools and processes for i18n/l10n, and am unpleasantly surprised with what I'm seeing. It seems there isn't a solid way of externalizing user-facing strings out of objective C files. Am I missing something?
Description of the problem:
There is a tendency to place English strings directly into the .m file, and the Apple documentation seems to encourage this. While this is also possible in Android, as least in Android there is a clear distinction between externalized and non-externalized strings. With iOS, on the other hand, code that calls for a string tends to look like this:
NSLocalizedString(#"There was an error loading the image.", nil)
In this case, "There was an error loading the image." is the key for this string resource. Therefore if I want to make another reference to the same string in some other place we have to again write code like this:
NSLocalizedString(#"There was an error loading the image.", nil)
But now I have to make sure that I spelled these two strings the same and there is no compile time check to help me confirm that. I could write a helper function called createErrorString, but that's not fun. And I could replace "There was an error loading the image." with a more sensible key like "ERROR_IMAGE_LOAD", but that does not seem to be a common practice, and Apple seems to discourage this sensible behavior. Here is what their documentation states:
"A common convention when developing applications is to use a key name
that equals the value in the language used to develop the
application."
It looks like Apple is recommending that you put the full English string in your source code. So I'll have to try to convince my colleagues to go against Apple's guidance.
Now that I've got all of these user-facing English strings (or keys) in the source code, Apple includes a tool called genstrings that parses the .m files, and spits out a Localizable.strings file that I can then send out for translation. This might work if you are only going to get your app localized one time, but in our company localization is an ongoing iterative process. Look at what the Apple documentation recommends:
"For subsequent runs, it is a good idea to save a copy of your current
strings files before running genstrings. You can then diff the new and
old versions to determine which strings were added to (or changed in)
your project. You can then use this information to update any already
localized versions of your strings files, rather than replacing those
files and localizing them again."
That doesn't seem very good. In Android and Windows8, you internationalize your source tree one time, and from that moment on your externalized strings are owned in the xml files where they belong; in iOS they are owned in source code (sort of) and then tabulated into some intermediate file (or is it?) by some crazy tool. Is the Localizable.strings file an intermediate file or should it be committed into git - we are still debating this at my company.
(And from what I can tell, this is only the beginning. In xib-land, which is where 90% of your user-facing strings live, there also seems to be an inefficient mechanism for l10n. Wil Shipley's article describes this at length.)
Does anyone have any suggestions on a good way to externalize strings in iOS? My main question concerns objective-C strings, but answers pertaining to xib files would also be much appreciated. Thanks!
I found the recommendation to name the key like the english string strange, too.
I name the keys, value e.g "Menu1SettingsTitle" = "Settings".
I dont need genstrings tool, just externalize manually.
And no, the string files is not an intermediate step, they should be in git.
However with that approach i noticed three drawbacks:
1) I detected duplicate names, but that can be moved to a common section for strings like "cancel, delete"
2) If you forget to put a string into that language file, it cannot be found and then the key is displayed, which looks very strange, of course. Otherwise with apples reccomendation, If the key is the english word, it looks "only english" but not worse.
3) The translation process is easier if english is always left, instead of "Menu1SettingsTitle". to solve that i put a comment above, but dont know if the translation service would be happy with that.
After a couple of hours searching I decided to use two different approaches: one for the storyboards and one for the text inside the .m files. The result are two files Localizable.strings for the Objective C text and the internationalized storyboard.
The update_storyboard_strings.sh can automatically extract translatable strings from storyboards and update strings files. The source code (by mikezang) can be found at:
http://forums.macrumors.com/showpost.php?p=16060008&postcount=4
For the objective C NLS I use another script around the xcode-tools by Frédéric Sagnes:
https://github.com/ndfred/xcode-tools
I had to call it for each language in order to get the desired results:
python scripts/xcode-tools/update_strings.py --import=MyProject/Base.lproj/Localizable.strings MyProject/Base.lproj/Localizable.strings
python scripts/xcode-tools/update_strings.py --import=MyProject/de.lproj/Localizable.strings MyProject/de.lproj/Localizable.strings
Now put both in one script and add it to your Xcode project as a last build phase.
Somehow I can't seem to get my localized launch image to work.
In the root of my project folder I have a localized Default#2x.png with both an English and a Dutch version.
Somehow the Dutch version is shown in all situations.
I have other localised files that work all right (Root.strings, Localizable.strings, InfoPlist.strings) when using English language.
I've looked up several related questions, but found no answer. Tried deleting the file all together en adding them again. After localizing the file I added the right picture to the right folder using 'Show in Finder' on the English version.
Other answers suggest that there's another copy of Default#2x.png somewhere that's in the way, but I can't seem to find one.
When I look at my project folder in Finder, some folders seem recursive (repeat themselves) though.
Any help is appreciated.
Launch images can not be localized. See the app programming guide:
All launch images (...) must reside in the top level of your app's bundle directory.