How to handle partially translated Localizable.strings file - ios

I have a Localizable.strings (base) file with, for example, the following strings:
"hello_world" = "Hello World";
"hello_world2" = "Hello World";
It is being translated to multiple languages. So I also have the following:
Localizable.strings (Chinese (Simplified))
Localizable.strings (Russian)
and etc.
Now the problem is that as the project grows, we have more and more new strings being added. But we don't want to wait for the translators to fully translate all the strings before we ship the app. Therefore, we end of having this Localizable.strings (Chinese (Simplified)) where hello_world2 is missing:
"hello_world" = "你好世界";
By default, the not translated string will be shown as the key "hello_world2" in the app. The question: is there a way to say, if a translation of key "hello_world2" doesn't exist, use the base translation instead?
Additional Info:
I know that for storyboard file, if it is partially translated, then it will just use the base translation for not translated strings. However, the same (nice) behaviour doesn't happen for other general .strings file. Really looking for a elegant way to solve this issue.

I find the easiest way to cope with this is to use the default string as the key. So you might have:
Base:
"Hello World" = "Hello World";
"Hello World 2" = "Hello World 2";
Chinese:
"Hello World" = "Hello World in Chinese";
If you haven't made any translations you just need to have at least one placeholder string in the file to avoid a compilation error, e.g. for a double space:
Russian:
/* Placeholder */
" " = " ";
It also makes the translator's job much easier!

Related

Sublime Text & Source Tree cannot see FileDiff in files generated using xml.File and fsObject in Excel VBA

We are looking at certain .yml files that store translation of a Rails application. For example, the structure of en.yml is as follows:
en:
blog:
left_navigation:
list_topic: "Blog topics blah blah"
articles:
show:
by_author: "By %{author}"
number:
currency:
format:
separator: "."
delimiter: ","
format: "%u%n"
admin:
blog:
topics:
form:
topic_name: "Topic name"
topic_parent: "Parent topic"
save: "Save"
cancel: "Cancel"
As part of our team's translation procedure, we have translators translate changes in Excel, then reexport the new .yml file via macros. The relevant code is:
...
FilePathAndName = ExportFolder & ExportLang & ".yml"
...
Set xmlFile = fsObject.createtextfile(FilePathAndName, True, True)
maxline = TargetRange.Rows.Count
i = 1
For Each mCell In TargetRange
line = mCell.Value
xmlFile.write line & IIf(i = TargetRange.Rows.Count, vbNullString, vbCrLf)
i = i + 1
Next mCell
xmlFile.Close
...
However, SublimeText cannot see FileDiff when looking at both files together under "Open Folder" interface. Similar, when loaded to Source Tree it says that the 2 files are not identical, but it fails to show the file difference.
We need this file difference to verify that the translations were done with correct syntax. Could somebody help us?
Thanks for your ideas #Odatnurd and #barrowc
The issue comes from the encoding of the second (destination file). Apparently it needed to be UTF-8. So I just resaved this file in Sublime Text with Encoding = UTF-8 and FileDiff worked again.
So a final question is, how do I make xml.File and fsObject in Excel VBA save the file in UTF-8 format?

How can I automatically check for missing localizations in Xcode?

SourceFile.m
NSLocalizedString(#"Word 1", #"");
NSLocalizedString(#"Word 2", #"");
de.lproj/Localizable.strings
"Word 1" = "Wort 1";
"Word 2" = "Wort 2";
fr.lproj/Localizable.strings
/* Missing Word 1 */
"Word 2" = "Mot 2";
Is there a script or a compiler setting that will check that all localised strings are translated in all supported locales?
You can use diff on the list of keys to see what's missing
Here's a shell script (let's call it keys.sh) to print out the keys of a given .strings file, sorted to stdout:
#!/bin/sh
plutil -convert json "$1".lproj/Localizable.strings -o - | ruby -r json -e 'puts JSON.parse(STDIN.read).keys.sort'
You can then use it combined with the <(cmd) shell syntax to compare keys between two localisations; for example to compare your Base.lproj and fr.lproj:
diff <(keys.sh Base) <(keys.sh fr)
Go under "Edit Scheme > Options" and check the "Show non-localized strings" box.
When you Build and Run you'll able to see warnings on Xcode command screen.
if you localized string like below:
lblTitle.text = NSLocalizedString("Lorem Ipsum", "")
then Xcode should throw an error message on terminal like below:
ERROR Lorem Ipsum not found in table Localizable of bundle CFBundle ...
For storyboards, Xcode will throw a similar error.
Not the perfect solution for your problem. But you could uses following plugin to check localization strings while coding.
https://github.com/questbeat/Lin
Also, I use to export localization string table from an Excel file or Google Sheet as a practice. This will make things easier and reduce lot of mistakes.
Check my example on how you can achieve it
To sum up: you can create a Run Script under Build Phase in which you execute a bash script like suggested from #AliSoftware to compare your Localizable.strings and in case some keys are missing from one compared to the other you could either stop the build and output those missing keys as error or you could just output them as error and not let the build continue.

NSLocalizedString is it really working?

I misunderstand NSLocalizedString.
I have a project with French and English .strings files.
In project target - Localizations I have 6 files in French and English.
In english.strings file:
"hello" = "world";
In french.strings file:
"hello" = "salut";
When I write a simple line of code to change label text:
exerciseDescription.text = NSLocalizedString(#"hello", #"no comment");
Output is: hello
I changed in iOS simulator : settings - general - international - language - French/English - Done
And output is again: hello
I thought it should be world or salut...
You're using it in correct way but not added properly,
Localized filename should always be named Localizable.strings, and that file is within the particular language folder, for English, en.lproj and for French fr.lproj like wise.
You are using it right, but as #Hemang mentioned you should change your filename to Localizable.strings as this is the default.
Furthermore I would like to suggest cleaning the build folder, and removing the application from the simulator. That helped for me in one case.

Are there any good tools for iOS pseudo localization? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking us to recommend or find a tool, library or favorite off-site resource are off-topic for Stack Overflow as they tend to attract opinionated answers and spam. Instead, describe the problem and what has been done so far to solve it.
Closed 9 years ago.
Improve this question
I'd like to start seeing how comprehensive we've been in our iOS code at localizing strings. We're not ready to go to translators yet, but I'd like to start testing with pseudo localization. Automating this process in a Localizable.strings file should be easy enough, but I can't seem to find any tools that do it. Frankly, I'd be satisfied with a script that just changed all my strings to "NOT ENGLISH!" if such a thing exists.
You can achieve this with the Translate Toolkit.
First you need to convert the .strings file to PO using the prop2po converter:
$ prop2po Localizable.strings en.po
This will create a PO file with the strings of the Localizable.strings file as source strings (in this case I'm using English as a source).
Once you have the PO file, rewrite it using podebug in the desired rewrite format.
$ podebug --rewrite=unicode en.po en_rewritten.po
Finally convert it back to the .strings format (note that you need to pass the original Localizable.strings file as a template):
$ po2prop en_rewritten.po rewritten.strings -t Localizable.strings
The resulting file will look something like this:
"Account: %#" = "Ȧƈƈǿŭƞŧ: %#";
"Add command" = "Ȧḓḓ ƈǿḿḿȧƞḓ";
"Add connection." = "Ȧḓḓ ƈǿƞƞḗƈŧīǿƞ."
I came across two solutions that haven't yet been mentioned here:
A free app called on the Mac App store that generates pseudolocalized .strings files based on your source code (drag-and-drop). It generates similar strings to those the OP provided in the question.
https://itunes.apple.com/us/app/pseudolocalizer/id503026674?mt=12
The online translation service Babble-on offers free pseudolocalized .strings files based on existing .strings files (other options available). They have the extra option of generating strings longer than the original English to test your GUI.
http://www.ibabbleon.com/pseudolocalization.html
although Translate Toolkit can provide a solution I've looked for a simpler approach using bash script.
create [changesDictionary.txt] file (see format at the end of this post) and run the following script with the language file as parameter:
# This script translate iOS strings file into pseudo languge for texting usage.
# the script create a sed change and replace file based on [changesDictionary.txt].
# the loop run across the input string file (ie. myFyle.strings)
# and replace the secong strings with the dictionary values.
# since the strings file is in BOM format (http://en.wikipedia.org/wiki/Byte_order_mark)
# the input is converted from UTF16 to UTF8.
sed -e 's/^"\(.*\)" = "\(.*\)"$/s\/\1\/\2\/g/' changesDictionary.txt > changesDictionary.sed
FILENAME=$1
while read -r; do
if [[ $REPLY = '/*'* ]] ; then
echo "$REPLY"
else
if [[ $REPLY = '' ]] ; then
echo "$REPLY"
else
if [[ $REPLY = '"'* ]] ; then
changes2=$(echo "$REPLY" | cut -d= -f2 | sed -f changesDictionary.sed)
changes1=$(echo "$REPLY" | cut -d= -f1 )
echo "$changes1=$changes2"
echo "$REPLY"
fi
fi
fi
done < <(iconv -f UTF-16 -t UTF-8 $FILENAME) | iconv -f UTF-8 -t UTF-16 >$FILENAME.new
The script look for a [changeDictionary.txt] file in the following format:
"a" = "á"
"b" = "β"
"c" = "ç"
"d" = "δ"
"e" = "è"
"f" = "ƒ"
"g" = "ϱ"
"h" = "λ"
"i" = "ï"
"j" = "J"
"k" = "ƙ"
"l" = "ℓ"
"m" = "₥"
"n" = "ñ"
"o" = "ô"
"p" = "ƥ"
"q" = "9"
"r" = "ř"
"s" = "ƨ"
"t" = "ƭ"
"u" = "ú"
"v" = "Ʋ"
"w" = "ω"
"x" = "ж"
"y" = "¥"
"z" = "ƺ"
"\ñ" = "\n"
"$δ" = "$d"
"$ï" = "$i"
you can use this example or create your own, please note tp the last 3 change string in the file. this is to restore end of lines and parameters to their regular state. I chose this approach to simplify the script (I think that the perfomance are not optimized).
We provide pseudo localization as part of our service at Tethras (www.tethras.com). Pseudo localization is free. We accent all of the characters in your strings and extend the length of the text by 30%. This will help you test not only for hard coded strings, but will also let you see what happens to your layouts due to text expansion during translation.
Examples:
Plain Text
Wè prôvïdè psèúdô lôçálïzátïôñ ás párt ôƒ ôúr sèrvïçè át Tèthrás
(www.tèthrás.çôm). ôñè twô thrèè ƒôúr ƒïvè sïx Psèúdô lôçálïzátïôñ ïs
ƒrèè. ôñè twô thrèè Wè áççèñt áll ôƒ thè çháráçtèrs ïñ ¥ôúr strïñgs
áñd èxtèñd thè lèñgth ôƒ thè tèxt b¥ 30%. ôñè twô thrèè ƒôúr ƒïvè sïx
Thïs wïll hèlp ¥ôú tèst ñôt ôñl¥ ƒôr hárd çôdèd strïñgs, bút wïll álsô
lèt ¥ôú sèè whát háppèñs tô ¥ôúr lá¥ôúts dúè tô tèxt èxpáñsïôñ dúrïñg
tráñslátïôñ. ôñè twô thrèè ƒôúr ƒïvè sïx sèvèñ èïght ñïñè tèñ
Localizable.strings
"Bring All to Front" = "Brïñg Áll tô ƒrôñt ôñè twô";
"Hide" = "Hïdè 12";
"Quit" = "Qúït 12";
"Hide Others" = "Hïdè Óthèrs ôñè ";
Kudos on wanting to test the localizability of your app prior to translation. This is going to save you a lot of time and energy during the actual translation process.
You can use the genstrings tool provided by Apple. It's all explained in the strings section of the Resource Programming Guide

Create localizable.strings from Code in iOS

I'm currently localizing my iOS-Application. This works pretty decent so far.
I've already created localizable.strings and several xib-files and so about 80% of the app is already translated.
But the App also loads data from a WebService which passes me a key, e.g.: "TITEL 1" as well as all supported languages (values) attached to it e.g: "Titel One" "Titel Eins" "Titolo Uno".
And now i would like to store those values in the according localizable.strings files.
For example:
Localizable.strings (English) should then contain:
"TITLE 1" = "Title One";
Localizable.strings (German) should then contain:
"TITLE 1" = "Titel Eins";
Localizable.strings (Italian) should then contain:
"TITLE 1" = "Titolo Uno";
How can I do this?
You will not be able to insert them in the localization strings at run time, if the webserver is managed by you, i suggest that you send wich language is the user using,
Please consider this example
//Get the language code
NSString* languageCode = [[NSLocale preferredLanguages] objectAtIndex:0];
//Now send the request to the server with the language you want
NSString *str = [NSString stringWithFormat:#"www.yourserve.com/yourfunctiom?lang=%#", languageCode];
//Request it
Now basing on the language that you receive in your server you will return the appropriate string
This may be stretching the frameworks a bit, but if you want to use Apple's string loading functions you could try to build an NSBundle in your document directory (a bundle is just a directory, after all), fill it with files from the server and then use NSLocalizedStringFromTableInBundle to get to your strings.
Not sure it is worth it compared to the approach in Omar Abdelhafith's answer, though.

Resources