Localizable a today extension - objective-c

I would like to know how can I use my Localizable.strings file to translate my widget ?
I try this but it doesn't working:
_result.text = [NSString stringWithFormat:NSLocalizedString(#"Votre avion a besoin de: %#USG", nil), #((int)number)];

You need to take the localizable string name in my case is str-name-demo
And you can use like a NSString
// 200 is the parameter
NSString *textStr = [NSString stringWithFormat: NSLocalizedString(#"str-name-demo", nil), 200];
NOTE: I assume you have the more settings ready to user NSLocalizedString method but you can see this tutorial to more understand it.
https://www.raywenderlich.com/64401/internationalization-tutorial-for-ios-2014
:)

Related

NSURL: Escape Backslash using NSCharacterSet

This may be a duplicate question, but I have checked all over and can't find a working answer for iOS9. -stringByAddingPercentEscapesUsingEncoding has been deprecated. I need to use -stringByAddingPercentEncodingWithAllowedCharacters
Below is the string that needs the backslashes escaped so that the API can authenticate the session and return a response.
NSString *base = #"http://domain.com/interface/?end=imember";
NSCharacterSet *set = [NSCharacterSet URLQueryAllowedCharacterSet];
NSString *key = [#"&client_key=KOB3N6KX9JXF2MRPO5U.BRFYM7TYVE\/16KIJVXZA6R7H\/1LD1K\/JYIYG7IZP2HA7NUYOVNT3CJG==&token=SGD7E9B29TQ.8HIITZ37XW3GLK5OGLZNLCDM=" stringByAddingPercentEncodingWithAllowedCharacters:set];
The standard URL Character sets don't escape the backslashes, I have tried them all:
URLUserAllowedCharacterSet
URLPasswordAllowedCharacterSet
URLHostAllowedCharacterSet
URLPathAllowedCharacterSet
URLQueryAllowedCharacterSet
URLFragmentAllowedCharacterSet
Please if someone could assist, I am rather new to development. Is it possible to create a custom allowed set which includes the backslash?
EDIT:
This is what the url should look like:
http://domain.com/interface/?end=imember&client_key=KOB3N6KX9JXF2MRPO5U.BRFYM7TYVE\/16KIJVXZA6R7H\/1LD1K\/JYIYG7IZP2HA7NUYOVNT3CJG==&token=SGD7E9B29TQ.8HIITZ37XW3GLK5OGLZNLCDM=
The exact solution for you answer is below.I got it from Zaph's answer.That is the better answer than other answer.
NSString *unescaped = #"http://domain.com/interface/?end=imember"];
NSString *escapedString = [unescaped stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]];
NSLog(#"escapedString: %#", escapedString);
URL Encoding Character Sets are
URLFragmentAllowedCharacterSet "#%<>[\]^`{|}
URLHostAllowedCharacterSet "#%/<>?#\^`{|}
URLPasswordAllowedCharacterSet "#%/:<>?#[\]^`{|}
URLPathAllowedCharacterSet "#%;<>?[\]^`{|}
URLQueryAllowedCharacterSet "#%<>[\]^`{|}
URLUserAllowedCharacterSet "#%/:<>?#[\]^`

NSLocalizedString with format

How would I use NSLocalizedString for this string:
[NSString stringWithFormat:#"Is “%#“ still correct for “%#“ tap “OK“ otherwise tap “Change“ to choose new contact details", individual.contactInfo, individual.name];
When using stringWithFormat before I've used it in the following manner:
[NSString stringWithFormat:#"%d %#", itemCount, NSLocalizedString(#"number of items", nil)];
[NSString stringWithFormat:NSLocalizedString(#"Is “%#“ still correct for “%#“ tap “OK“ otherwise tap “Change“ to choose new contact details", #"Query if parm 1 is still correct for parm 2"), individual.contactInfo, individual.name];
Given sentences can be constructed with the variable parts in a different order in some languages then I think you should use positional arguments with [NSString stringWithFormat:]:
NSString *format = NSLocalizedString(#"number_of_items", #"Number of items");
Which would load the following string for English:
#"Is \"%1$#\" still correct for \"%2$#\" tap \"OK\" otherwise tap \"Change\" to choose new contact details"
And perhaps something else for French (I don't know French so I won't attempt a translation, but it could well have the first and second argument in a different order):
"French \"%2$#\" french \"%1$#\" french"
And you can safely format the string as normal:
NSString *translated = [NSString stringWithFormat:format individual.contactInfo, individual.name];
I just want to add one very helpful definition which I use in many of my projects.
I've added this function to my header prefix file:
#define NSLocalizedFormatString(fmt, ...) [NSString stringWithFormat:NSLocalizedString(fmt, nil), __VA_ARGS__]
This allows you to define a localized string like the following:
"ExampleScreenAuthorizationDescriptionLbl"= "I authorize the payment of %# to %#.";
and it can be used via:
self.labelAuthorizationText.text = NSLocalizedFormatString(#"ExampleScreenAuthorizationDescriptionLbl", self.formattedAmount, self.companyQualifier);
Swift
//Localizable.strings
"my-localized-string" = "foo %# baz";
Example:
myLabel.text = String(format: NSLocalizedString("my-localized-string",
comment: "foo %# baz"), "bar") //foo bar baz

Keychain kSecValueData with weird not-showing characters at last

I've been searching a solution for this problem, but it seems I'm the only one on the Internet who has encountered a problem like this.
I'm using the keychain wrapper class provided by Apple to store the user and password as it should be stored. When I want to get the user value back, is as easy as doing:
NSString *user = [keychain objectForKey:(id)kSecAttrAccount];
Retriveing the password should be as straightforward as the username:
NSString *pass = [keychain objectForKey:(id)kSecValueData];
But after that, trying to print them with an NSLog, nothing is shown on console AFTER the pass. For example:
NSLog(#"user: <%#>, pass: <%#>, something after the pass", user, pass);
The output of this NSLog is:
user: <123456>, pass: <5433
Invoking [pass length] gives me always a number greater than the actual length of the pass (in this example, 10, when I would say its length is actually 4).
I have no idea of what's going on. I made a workaround to patch this problem while I try to find a proper solution (looking every character's integer value and allowing only the ones which are numbers, letters and some symbols).
Thank you in advance!
The problem here is that you are trying to store a CFDataRef object as an NSString object, and then print it is a string using %#. It is a data object, not a string. If you'd like to see it as a string, you must first convert it into a string. Try something like the code below to convert it into a string before you try to log it:
NSData *passData = [keychain objectForKey:(id)kSecValueData];
NSString *pass = [[NSString alloc] initWithBytes:[passData bytes] length:[passData length] encoding:NSUTF8StringEncoding];
kSecValueData is of type: typedef const void * CFTypeRef;
You shouldn't typecast it to a NSString.
Try directly posting it into the NSLog like this.
NSLog(#"user <%#> pass <%#>", [keychain objectForKey:(id)kSecAttrAccount], [keychain objectForKey:(id)kSecValueData]);
Goodluck!

IPhone Navigation-Based Application Model

I am making a Navigation-Based Application for the IPhone and I start off with a big list of names (about 100) and I was wondering what would be the quickest and most efficient way to alter the content according to what name the user tapped on in the list.
Right now I change the content according to what the title is like this:
NSString *comparisonString = #"Bill Clinton";
NSString *comparisonString2 = #"Bob Dole";
if (self.title == comparisonString) {
NSString *alterString = [NSString stringWithFormat: #"He is a democrat from North Carolina "];
[appDelegate setModelData:alterString];
}
else if (self.title == comparisonString2) {
NSString *alterString = [NSString stringWithFormat: #"He was born into a family in New York City... "];
[appDelegate setModelData:alterString];
}
would this be the best way to do this? Seems like a lot of code would be repeated. I am brand new to Objective-C and developing for the IPhone, any advice will help me. Thank you!
What you've written so far in those two conditions is equivalent to this (with no if statement):
NSString *alterString = [NSString stringWithFormat: #"Content for %#!", self.title];
[appDelegate setModelData:alterString];
Hope that helps.
All you are doing is changing that same part of the string in both the if and else statements (and presumably more else statements later)
EDIT
ok, looking now at the edited question, you basically have a look up table now. So self.title is the key and you want to use that to lookup another string.
One way to do this is to create a plist with a dictionary that maps each name to a string. Then load that plist and look up the name from there. Something like this:
NSDictionary* people = [NSDictionary dictionaryWithContentsOfFile:pathToThePlist];
NSString *content = [people objectForKey:name];
(BTW, right now you are using '==' for string comparison, you want to use -[NSString isEqualToString:] for that in the future.

Possible to use variables and/or parameters with NSLocalizedString?

I have tried using a variable as an input parameter to NSLocalizedString, but all I am getting back is the input parameter. What am I doing wrong? Is it possible to use a variable string value as an index for NSLocalized string?
For example, I have some strings that I want localized versions to be displayed. However, I would like to use a variable as a parameter to NSLocalizedString, instead of a constant string. Likewise, I would like to include formatting elements in the parameter for NSLocalizedString, so I would be able to retrieved a localized version of the string with the same formatting parameters. Can I do the following:
Case 1: Variable NSLocalizedstring:
NSString *varStr = #"Index1";
NSString *string1 = NSLocalizedString(varStr,#"");
Case 2: Formatted NSLocalizedString:
NSString *string1 = [NSString stringWithFormat:NSLocalizedString(#"This is an %#",#""),#"Apple"];
(Please note that the variable can contain anything, not just a fixed set of strings.)
Thanks!
If what you want is to return the localized version of "This is an Apple/Orange/whatever", you'd want:
NSString *localizedVersion = NSLocalizedString(([NSString stringWithFormat:#"This is an %#", #"Apple"]), nil);
(I.e., the nesting of NSLocalizedString() and [NSString stringWithFormat:] are reversed.)
If what you want is the format to be localized, but not the substituted-in value, do this:
NSString *finalString = [NSString stringWithFormat:NSLocalizedString(#"SomeFormat", nil), #"Apple"];
And in your Localizable.strings:
SomeFormat = "This is an %#";
I just want to add one very helpful definition which I use in many of my projects.
Inspired by androids possibility, I've added this function to my header prefix file:
#define NSLocalizedFormatString(fmt, ...) [NSString stringWithFormat:NSLocalizedString(fmt, nil), __VA_ARGS__]
This allows you to define a localized string like the following:
"ExampleScreenAuthorizationDescriptionLbl"= "I authorize the payment of %# to %#.";
and it can be used via:
self.labelAuthorizationText.text = NSLocalizedFormatString(#"ExampleScreenAuthorizationDescriptionLbl", self.formattedAmount, self.companyQualifier);
For swift :
let myString = String(format: NSLocalizedString("I authorize the payment of %d ", comment: ""), amount)
extension String {
public var localizedString: String {
return NSLocalizedString(self, comment: "")
}
public func localizedString(with arguments: [CVarArg]) -> String {
return String(format: localizedString, arguments: arguments)
}
}
Localizable.string:
"Alarm:Popup:DismissOperation:DeviceMessage" = "\"%#\" will send position updates on a regular basis again.";
"Global:Text:Ok" = "OK";
Usage:
let message = "Alarm:Popup:DismissOperation:DeviceMessage".localizedString(with: [name])
and
let title = "Global:Text:Ok".localizedString
It turns out that a missing target entry is to blame. Just checking that my current build target includes the Localizable.string file solved the problem!
If you have more than one variable in your localized string can you use this solution:
In Localizable.strings
"winpopup" = "#name# wins a #type# and get #points# points(s)";
And use stringByReplacingOccurrencesOfString to insert the values
NSString *string = NSLocalizedString(#"winpopup", nil); //"#name# wins a #type# and get #points# points(s)"
NSString *foo = [string stringByReplacingOccurrencesOfString:#"#name#" withString:gameLayer.turn];
NSString *fooo = [foo stringByReplacingOccurrencesOfString:#"#type#" withString:winMode];
NSString *msg = [fooo stringByReplacingOccurrencesOfString:#"#points#" withString:[NSString stringWithFormat:#"%i", pkt]];
NSLog(#"%#", msg);
Your ideas should work. But if you are getting back the input parameter, that means that the input parameter was not found as a key in your Localizable.strings file. Check the syntax and location of that file.
This works for me:
NSMutableString *testMessage = [NSMutableString stringWithString:NSLocalizedString(#"Some localized text", #"")];
testMessage = [NSMutableString stringWithString:[testMessage stringByAppendingString:someStringVariable]];