How to Localize NSString with format [duplicate] - objective-c

This question already has an answer here:
iOS: How to localize strings with multiple interpolated parameters?
(1 answer)
Closed 5 years ago.
How to localize the NSString with format.
int value = 20;
NSString *str = #"hello";
textLabel.text = [NSString stringWithFormat:#"%d %#", value, str];
I tried
textLabel.text = [NSString stringWithFormat:NSLocalizedString(#"%d %#", #"%d %#"), value, str];
but didn't work. Any help is appreciated.

Your localized string itself must be a format pattern:
"ValueAndStringFMT" = "Value %1$d and string %2$#";
And in your code:
textLabel.text = [NSString
stringWithFormat:NSLocalizedString(#"ValueAndStringFMT"),
value, str
];
Why %1$d and not just %d? So you can change the order. E.g. in some language you may like to have the order swapped:
"ValueAndStringFMT" = "Cadena %2$# y valor %1$d";
Of course, that is somewhat dangerous as if someone uses more placeholders than your string call offers or uses the wrong types, your app may crash. If you want to be safe, you do a search an replace instead:
"ValueAndStringFMT" = "Value [[VALUE]] and string [[STRING]]";
And in your code:
NSString * string = NSLocalizedString(#"ValueAndStringFMT");
string = [string stringByReplacingOccurrencesOfString:#"[[VALUE]]"
withString:#(value).stringValue
];
string = [string stringByReplacingOccurrencesOfString:#"[[STRING]]"
withString:str
];
textLabel.text = string;
That way the worst case scenario is that a placeholder is not expanded, meaning the placeholder is visibly printed on screen but at least your app won't crash because someone messed up the localization strings file.
If you need to localize one of the format variables, then you need to do that first in an own step:
NSString * str = NSLocalizedString(#"hello");

Related

Compare char array with string in iOS program [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
How to compare char* and NSString?
If I have:
char XYZ[256]="";
how can I compare this char array with another string (e.g. "testing") in an iOS Objective-C program?
Use strcmp
char XYZ[256] = "";
char *string = "some other string";
int order = strcmp(XYZ, string);
RETURN VALUES
The strcmp() and strncmp() functions return an integer greater than, equal to, or less than 0, according as the string s1 is greater than, equal to, or less than the string s2. The comparison is done using unsigned characters, so that \200' is greater than\0'.
You can also convert them up to NSString, this makes a lot overhead, but brings your string to Objective-C object:
char XYZ[256] = "";
NSString *s = [[NSString alloc] initWithBytes:XYZ length:strlen(XYZ) encoding:[NSString defaultCStringEncoding]];
NSString *testing = #"testing";
if ([testing compare:s] == NSOrderedSame) {
NSLog(#"They are hte same!");
}
Note that strcmp is A LOT faster!
Just because it is iOS doesnt mean that you cannot "#include" string.h and use "strcmp" (now as stated above).
The alternative would be to create a new NSString and compare it using a comperable iOS Objective-C call:
NSString myString = [NSString stringWithCString:XYZ encodingNSASCIIStringEncoding];
if(YES == [myString isEqualToString:#"testing"]){
// Perform Code if the strings are equal
}else{
// Perform Code if the strings are NOT equal
}

EXC_BAD_ACCESS strange Hex to String conversion [duplicate]

This question already has answers here:
Hex in a stringWithFormat BAD ACCESS
(2 answers)
Closed 8 years ago.
I'm stuck.
I give you the exact code which I use, not a sample:
So, I make two strings like this:
DestChoice = [NSString stringWithFormat:#"%lX", [DestField integerValue]];
SourceChoice = [NSString stringWithFormat:#"%lX", [SourceField integerValue]];
So the user write the Source/Dest in Decimal value but they are stocked as hex in a string, and then I have a button which reformat the source & dest like this:
NSString * CommandReadyToSend = [NSString stringWithFormat:#"X:0/%#,%#\r", DestChoice, SourceChoice];
My code is working, BUT, strangly some values makes a EXC_BAD_ACCESS at the CommandReadyToSend part...
Example: If I write 1 in my text field => I receive 1 (hex value) as result in DestChoice
If I write 10 in my text field => I receive A in DestChoice
BUT If I write 31 in the text field, I'm supposed to get 1F, but I get a EXC_BAD_ACCESS...
Same thing with 29 (dec value)
It seems that certains hex value can't be reformatted to string, I don't understand...
Seems to be working for me, the cause must be elsewhere.
NSString *destChoice = [NSString stringWithFormat:#"%lX", 1];
NSString *sourceChoice = [NSString stringWithFormat:#"%lX", 31];
NSString *commandReadyToSend = [NSString stringWithFormat:#"X:0/%#,%#\r", destChoice, sourceChoice];
NSLog(#"%#", commandReadyToSend);
2012-05-10 13:56:29.092 test[9383:707] X:0/1,1F
-
btw; If DestField is a UITextField then you should be using [DestField.text integerValue]; - this is probability your problem.

Split an NSString to access one particular piece

I have a string like this: #"10/04/2011" and I want to save only the "10" in another string. How can I do that?
NSArray* foo = [#"10/04/2011" componentsSeparatedByString: #"/"];
NSString* firstBit = [foo objectAtIndex: 0];
Update 7/3/2018:
Now that the question has acquired a Swift tag, I should add the Swift way of doing this. It's pretty much as simple:
let substrings = "10/04/2011".split(separator: "/")
let firstBit = substrings[0]
Although note that it gives you an array of Substring. If you need to convert these back to ordinary strings, use map
let strings = "10/04/2011".split(separator: "/").map{ String($0) }
let firstBit = strings[0]
or
let firstBit = String(substrings[0])
Either of these 2:
NSString *subString = [dateString subStringWithRange:NSMakeRange(0,2)];
NSString *subString = [[dateString componentsSeparatedByString:#"/"] objectAtIndex:0];
Though keep in mind that sometimes a date string is not formatted properly and a day ( or a month for that matter ) is shown as 8, rather than 08 so the first one might be the worst of the 2 solutions.
The latter should be put into a separate array so you can actually check for the length of the thing returned, so you do not get any exceptions thrown in the case of a corrupt or invalid date string from whatever source you have.
Its working fine
NSString *dateString = #"10/10/2010";//Date
NSArray* dateArray = [dateString componentsSeparatedByString: #"/"];
NSString* dayString = [dateArray objectAtIndex: 0];
Objective-c:
NSString *day = [#"10/04/2011" componentsSeparatedByString:#"/"][0];
Swift:
var day: String = "10/04/2011".componentsSeparatedByString("/")[0]
Use [myString componentsSeparatedByString:#"/"]
I have formatted the nice solution provided by JeremyP above into a more generic reusable function below:
///Return an ARRAY containing the exploded chunk of strings
+(NSArray*)explodeString:(NSString*)stringToBeExploded WithDelimiter:(NSString*)delimiter
{
return [stringToBeExploded componentsSeparatedByString: delimiter];
}
Swift 3.0 version
let arr = yourString.components(separatedBy: "/")
let month = arr[0]

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]];

stringByAppendingFormat not working

I have an NSString and fail to apply the following statement:
NSString *myString = #"some text";
[myString stringByAppendingFormat:#"some text = %d", 3];
no log or error, the string just doesn't get changed. I already tried with NSString (as documented) and NSMutableString.
any clues most welcome.
I would suggest correcting to (documentation):
NSString *myString = #"some text";
myString = [myString stringByAppendingFormat:#" = %d", 3];
From the docs:
Returns a string made by appending to the receiver a string constructed from a given format string and the following arguments.
It's working, you're just ignoring the return value, which is the string with the appended format. (See the docs.) You can't modify an NSString — to modify an NSMutableString, use -appendFormat: instead.
Of course, in your toy example, you could shorten it to this:
NSString *myString = [NSString stringWithFormat:#"some text = %d", 3];
However, it's likely that you need to append a format string to an existing string created elsewhere. In that case, and particularly if you're appending multiple parts, it's good to think about and balance the pros and cons of using a mutable string or several immutable, autoreleased strings.
Creating strings with #"" always results in immutable strings. If you want to create a new NSMutableString do it as following.
NSMutableString *myString = [NSMutableString stringWithString:#"some text"];
[myString appendFormat:#"some text = %d", 3];
I had a similar warning message while appending a localized string. This is how I resolved it
NSString *msgBody = [msgBody stringByAppendingFormat:#"%#",NSLocalizedString(#"LOCALSTRINGMSG",#"Message Body")];