Swift Localization: String String interpolation - swift

I am trying to add multilanguage support to my app. I am doing this by replacing all my User visible Strings with localized strings. For strings like "Cancel", this is easy. But I have just as many strings that are interpolated with information. And the hard part is that each language would build the sentence differently.
For example: How would I localize the following String:
"Please enter the 4-digit Code sent to you at (user.PhoneNumber)"
In German, I want the string to look like this:
"Bitte gebe den 4-Ziffer Code ein, den wir dir an (user.PhoneNumber) gesendet haben"
Or in French:
"Entrez le code à 4 chiffres qui vous a été envoyé à (user.PhoneNumber)"
I am trying to find a way to use some kind of variable inside of my localization file like this (I know that this does not work):
Inside my ViewController:
title.text = "Please enter the 4-digit Code sent to you at %phoneNumber%".localized
Inside my Localizable.string
"Please enter the 4-digit Code sent to you at %phoneNumber%" = "Bitte gebe den 4-Ziffer Code ein, den wir dir an %phoneNumber% gesendet haben"
What's the best practice to do this? This must be some common issue people are having. Languages are so different!

my localized file example:
"email_error_message" = "a link is sent to %# please verify"
Actual code implementation:
let email = smth#email.com
let message = NSLocalizedString("email_error_message", comment: "error, wrong email")
let str = String.localizedStringWithFormat(message, email) //we want to replace %# with email.
Print(str)
** Please note the replaced string/char, in the above case (email) won't be localized.

Related

Restore String Interpolation AFTER value replace

Given a str: "My name is Gustavo", that was created with "My name is \(foo.name)"
Is it possible to get the string "My name is \(foo.name)" after the value was replaced?
In other words, is it possible to find out "My name is \(foo.name)", having "My name is Gustavo"?
Edit: If I can get to "My name is ", a.k.a. the hard coded string from all strings that were build dynamically, that would be a solution.
No, this is not possible. In fact, "My name is \(foo.name)" is not even included in the compiled code. Instead, Swift-5 compiler generates code equivalent to this:
let str = String(stringInterpolation: {
var temp = String.StringInterpolation(literalCapacity: 11, interpolationCount: 1)
temp.appendLiteral("My name is ")
temp.appendInterpolation(foo.name)
return temp
}())
This article contains details on how string interpolation is implemented in Swift-4 and Swift-5.

Fill a Word document form with OLE in C++ Builder

I want to have my C++ Builder application fill the following Word document form :
http://oesv.at/media/media_vereinsservice/media_formulare/Zuschlagsberechnung-Alpin_06-07.doc
I manage to do this with Ole procedures calling OpenOffice Writer but for users of my application who don't have OpenOffice installed but Microsoft Office instead I want to call Ole procedures with Word.
I tried without success to find and see the structure of this document file: like a tree map with : the document object, the Fields or FormFields objects, their properties "Field", which have properties Result, which is a range object having property Text and the document property Selection which has the procedure "TypeText". But no structure view available, so just guessing in the dark how the document file is structured.
Here below two solutions I tried without success:
first: the commented part consist on selecting the text input field and have this current selection in the document call its procedure "TypeText". This throws an error saying the object I try to modify is in a protected area of the document : "EOleException : Cette méthode ou propriété n'est pas disponible car l'objet fait référence à une zone protégée d'un document.".
second: the code below throws an error "EOleException : Le type ne correspond pas" that can be translated "Type mismatch" on the line "Result.OlePropertySet("Text", vInputText);". I have tried to pass a WideString or directly the default string format for my project without success.
try
{
//---ouverture de Word
vMSWord.OlePropertySet("Visible", false);
//---ouverture du fichier
vFileName = Variant(wFile.c_bstr());
vWDocuments = vMSWord.OlePropertyGet("Documents");
vWDocument = vWDocuments.OleFunction("Open", vFileName);
Variant fields, field;
fields = vWDocument.OlePropertyGet("FormFields");
for (int i=1; i<=fields.OlePropertyGet("Count"); i++)
{
Variant field = fields.OleFunction("Item",(Variant)i);
//field.OleFunction("Select");
//Variant selection = vMSWord.OlePropertyGet("Selection");
//selection.OleProcedure("TypeText",WideString("My input text"));
Variant Result = field.OlePropertyGet("Result"); // result = objet range
Variant vInputText = Variant(WideString("My input text").c_bstr());
Result.OlePropertySet("Text", vInputText);
}
//---sauvegarde en fichier texte
vFileName = Variant(wNewFile.c_bstr());
ShowMessage("Saveas :");
vWDocument.OleProcedure("Saveas", vFileName);
}
catch(Exception &e)
{
ShowMessage(AnsiString(e.ClassName())+ e.Message);
}
I do it so:
...
String FieldName = "SomeFormFieldName"; // Try WideString
String Text = "SomeText"; // Try WideString
Variant Field = Document.OlePropertyGet("FormFields").OleFunction("Item", (OleVariant)FieldName);
Field.OlePropertyGet("Range").OlePropertySet("Text", Text);
...
But you must be shure that the Document contains fields is exactly of FormFields type not MergeField or others. Also you must set the Bookmark property for Fields inside the template document and use it as FieldName.

How do I force input to be string only?

I need the user to input a title of a book.
I need to make sure they input string only.
This is where I'm at so far, any guidance please.
Do { $strTitle = Read-host "Enter the book title"}
while ($strTitle -eq "")
What do you mean by string? alpha characters only?
You could try a regular expressions.
Regular Expression to match only alphabetic characters
http://powershell.com/cs/blogs/tobias/archive/2011/10/27/regular-expressions-are-your-friend-part-1.aspx
Code to check for alpha characters:
Do {
$strTitle = Read-host "Enter the book title"
} until ($strTitle -notMatch "[^[:alpha:]]")

generating Localizable.strings creates strange output

When I use genstrings -o en.lproj *.m it generates the Localizable.strings file with entries in this structure:
/* this is the text: %# ID: %02X */
"this is the text: %# ID: %02X" = "this is the text: %1$# ID: %2$X";
Please notice that it makes from %# -> %1$#
Why is this? I always have to change it back to %# manually.
Thanks
Did you use the "-j" option? It produces java localized string (which have the format like %1$#).
[EDIT]
Sorry, looked at the wrong manual page. Please use the option -noPositionalParameters to turn off generation of positional parameters. -> Info's here
You don't need to change it back, since %1$# refers to the first argument given to your format string.
Actually, in a case different from yours, it might happen that the order of the arguments changes from a translation to another. For example, if your code uses a format to display some player property value like:
let fmt = NSLocalizedString("Player property value", comment: "The player property value")
String(format:fmt, playerName, playerProperty, value)
You might have in the "en.lproj/Localizable.strings":
/* The player property value */
"Player property value" = "Player %1$#'s %2$# is %3$d"
and in the "fr.lproj/Localizable.strings":
/* The player property value */
"Player property value" = "Le %2$# du joueur %1$# is %3$d"
or:
/* The player property value */
"Player property value" = "Le joueur %1$# a %3$d points de %2$#"

How to delete particular string from paragraph

Hi Friends, I have a small question,
I have a paragraph of string, now I want to delete some words from that para
aaaaaaaaaaaaaaaaa*bbbbbbbbb*aaaaaaaaaaaaaa.
Now, suppose I want to delete the "bbbbbbbb" fromthe above para and I am using the following method
mySpeechText = [[mySpeechText stringByReplacingOccurrencesOfString:strTemp withString:#""] retain];
but this method is replacing the "bbbbbbbb" with blank spaces, ie, " " and I am getting
aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaa;
and I want aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; without any space. so how can I delete the "bbbbbbbb" rather replacing it. Thanks-
If I am not clear plz let me know.
Try this
mySpeechText=[mySpeechText stringByTrimmingCharactersInSet:
[NSCharacterSet characterSetWithCharactersInString:#"bbbbbbbb"]];