Currently I am working on a Localization for my App. When I want to logout the user, I want to tell his name in the alert. So I used the following code:
let name = "Matthias Kremer"
let formatedString = NSLocalizedString("logoutTitleWithName", comment: " abmelden?")
print( String.localizedStringWithFormat(formatedString, name))
The Localizable.string file looks like that:
"logoutTitleWithName" = "%d abmelden";
I supposed to get the following outlet:
Matthias Kremer abmelden
But instead it is
281,600 abmelden
It seams like the String is converted in a Number somehow. Does anybody knows how to deal with this?
Change
"logoutTitleWithName" = "%# abmelden";
%d is a repacement for decimal value while %# for a string
Related
I am trying to get string from string file called "Common.strings" that I have created to store some non translated strings like URLs and names.
So, to do that I created the a strings file called "Common":
I find the way using localizedString like below:
Bundle.main.localizedString(forKey: "api_url", value: "", table: "Common")
There are another way to do that ? The code that I am using is right ?
I am asking cause I don't want a "localized" string
Declare the constant values as such in code, there is no need to create a .strings file.
E.g. let urlString = "http://mywebsite.com"
You could also put it inside a struct to effectively namespace your constants:
struct Constants {
static let urlString = "http://www.mywebsite.com"
}
Giving you something like: let baseUrlString = Constants.urlString
I'm going through the string reference documentation because I'm curious to learn what's available or at my disposal. I'm having trouble implementing a string init method in a playground to see how it works. I'd like to test if this string init method can accept a string and a locale object to see if the output is a translated string. Of course I'm using auto complete as a handicap so what I've tried so far is that I attempt to type String.init but the init method I want to test doesn't show up in the list. How do I use this method?
Apple reference doc
Also, I'm familiar with localization. Again, this was just a test to see how the function works exactly.
init(format: String, locale: Locale?, _ args: CVarArg...)
That String initializer doesn't do any language translation. It formats numbers based on the provided locale.
Here's an example using a US English and a Germany German locale:
let fmtStrUS = String(format: "%# %.2f %d", locale: Locale(identifier: "en_US"), "Hello", 1234.5, 12345)
let fmtStrDE = String(format: "%# %.2f %d", locale: Locale(identifier: "de_DE"), "Hello", 1234.5, 12345)
The results are:
Hello 1,234.50 12,345
Hello 1.234,50 12.345
Note that the only difference is how the numbers are formatted. No text translation is done.
If you only need to format a number, use a NumberFormatter. But if you are localizing more text that includes numbers, this String init is the better approach.
This can be combined with standard localization using NSLocalizedString.
You may have code something like the following:
let messageFormat = NSLocalizedString("Hello %.2f %d", comment: "Fun with localization")
let fullMessage = String(format: messageFormat, locale: Locale.current, someDoubleVariable, someIntVariable)
Then in en.strings you would have:
"Hello %.2f %d" = "Hello %.2f %d"
And in de.strings you would have:
"Hello %.2f %d = "Gutentag %.2f %d"
So the text translation is done as normal through strings files but this String initializer lets you ensure the numbers are formatted for the current user's locale.
Please note that if you use this with Locale.current you may wish to use localizedStringWithFormat instead which assumes the current locale.
let fullMessage = String.localizedStringWithFormat(messageFormat, someDoubleVariable, someIntVariable)
I set the language of the simulator to French. To check the language code, I used a couple of solutions:
let lang = NSLocale.autoupdatingCurrent.languageCode
print(lang)
let pre = Locale.preferredLanguages[0]
print(pre)
The result are:
Optional("en")
fr-US
What I expected to get is:
fr
How can I achieve that?
Try below code,
let requiredString = pre.components(separatedBy: "-").first ?? pre //fr
/*if pre.contains("-"), then requiredString = before("-") else requiredString = pre*/
print(Locale.components(fromIdentifier: Locale.preferredLanguages[0])["kCFLocaleLanguageCodeKey"]!)
this will print language code only.
If you want the Language instead of the Language_Region, then I suggest to take the sub string before the _ from the string to neglect the Region.
(If the string contains no _ then take the entire string since it doesn't contain the region in it)
I would like to be able to store a phone number in a standard way, e.g. just the digits (potentially with the '+' for the country code), something like these examples...
"17185555555"
"+17185555555"
"+447788888888"
... but I'd like to be able to DISPLAY it to a user in a properly formatted way, e.g.
"1 (718) 555-5555"
"+1 (718) 555-5555"
"+44 (7788) 888888"
...WITHOUT having to rely on a CNContactViewController to format it.
Obviously doing this just for US/Canada numbers would be easy - it's just one standard format - but I'd like it to be generic so it can work for numbers from any country. I know this question gives an answer for US/Can numbers only.
I know that I could use a CNContactViewController to display the number in the correct format, e.g.
let newContact = CNMutableContact()
newContact.givenName = "John"
newContact.familyName = "Smith"
newContact.phoneNumbers = [CNLabeledValue(label: CNLabelPhoneNumberiPhone, value: CNPhoneNumber(stringValue:"17185555555"))]
let contactView = CNContactViewController(forContact: newContact)
self.presentViewController(contactView, animated: true, completion: nil)
This will show the number on screen properly formatted, i.e.
1 (718) 555-5555
... so I know that something in the framework can do it. (This approach works for other country phone number formats, as long as you prefix the number with the right country code - e.g. "+44...")
From various other questions I know that I can get the raw digits and country code out of a CNContact, e.g. (following above example)
for pNumber: CNLabeledValue in newContact.phoneNumbers {
let value = pNumber.value as! CNPhoneNumber
let cc = value.valueForKey("countryCode") as? String
let digits = value.valueForKey("digits") as? String
print("cc:" + cc + ", " + digits)
}
... but this will just show the unformatted string again - not what I am looking for in this case.
Any help or other recommended approaches really appreciated!
My answer proposes another lib
You can format your numbers with this lib.
And you can use like this:
let phoneNumber: NBPhoneNumber = try phoneUtil.parse("17185555555", defaultRegion: yourRegion)
let formattedString: String = try phoneUtil.format(phoneNumber, numberFormat: .E164)
I have a String saved in an NSDictionary named accountInfoDict that I received from my iPhone app. I want to show this string using Swift in my watch kit app.
This is how I am trying to display the string:
self.pointsLabel.setText(String(format: "%# points",
arguments: accountInfoDict!["points"] as? String))
I get an error message saying:
Cannot convert value of type 'String?' to expected argument type '[CVarArgType]'
Does anyone know what this means and how I can format my string to make this work? Thanks!
Note:
The string displays correctly when I do it like this:
self.pointsLabel.setText(accountInfoDict!["points"] as? String)
But I want to add "points" to the end of the string.
You can just achieve it by writing it like:
// If point is nil, shows 0
let point = accountInfoDict!["points"] as? String ?? "0"
self.pointsLabel.setText("\(point) Points")
Also you can write it as:
self.pointsLabel.setText(String(format: "%# points", arguments: [point]))
More conveniently:
self.pointsLabel.setText(String(format: "%# points", point))
Break it into 2 lines:
let points = accountInfoDict!["points"] as! String
self.pointsLabel.setText(String(format: "%# points",points))
You can also usestring interpolation in Swift:
self.pointsLabel.setText("\(accountInfoDict!["points"]!) points")