The question title says it all, really. In swift you use "\()" for string interpolation of a variable. How does one do it with Objective-C?
There is no direct equivalent. The closest you will get is using a string format.
NSString *text = #"Tomiris";
NSString *someString = [NSString stringWithFormat:#"My name is %#", text];
Swift supports this as well:
let text = "Tomiris"
let someString = String(format: "My name is %#", text)
Of course when you use a format string like this (in either language), the biggest issue is that you need to use the correct format specifier for each type of variable. Use %# for object pointers. Use %d for integer types, etc. It's all documented.
#rmaddy's Answer is the gist of it. I just wanted to follow up on his comment that "It's all documented". Well, these symbols like %# and %d are called String Format Specifiers the documentation can be found at the following links.
Formatting String Objects
https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Strings/Articles/FormatStrings.html
String Format Specifiers
https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.html#//apple_ref/doc/uid/TP40004265-SW1
Just telling us noobs "It's all documented" isn't very helpful because often (if you're like me) you googled to find this stackoverflow post at the top of the SEO. And taking the link in hopes of finding the original documentation!
Related
What should be the correct format of the below to print *newString ?
NSString *newString = #"Hello this is a string!";
NSLog(#newString);
NSLog works pretty much as a C printf, with the addition of the %# string format specifier, which is meant for objects. Being NSString an object, %# is the right format to use:
NSString *newString = #"Hello this is a string!";
NSLog(#"%#", newString);
For as tempting as it can look, NEVER do
NSLog(newString); //NONONONONO!
since it's a terrible practice that may lead to unexpected crashes (not to mention security issues).
More info on the subject: Warning: "format not a string literal and no format arguments"
The # symbol is just a shorthand for specifying some common Objective-C objects. #"..." represents a string (NSString to be specific, which is different from regular C strings), #[...] represents an array (NSArray), #{...} represents a dictionary (NSDictionary).
On the first line, you've already specified a NSString object using the # sign. newString is now an NSString instance. On the second line, you can just give it's variable name:
NSLog(newString);
You could theoretically just give the variable name, but it is a dangerous approach. If newString has any format specifiers, your app may crash/mess up (or access something that it shouldn't be accesing) because NSLog would try to read the arguments corresponding to the format specifiers, but the arguments don't exist. The safe solution would be NSLog(#"%#", newString);. The first argument to NSLog is now hard-coded and can't be changed. We now know that it will expect a single argument, that we are providing that argument, newString, so we are safe.
Because you've already specified a string and just passing that instance to NSLog, you don't need the # sign again.
So I have done some searching around so that I could see what it was I was doing with my code, and I couldn't find any answers as to what this very one specific line of code does.
NSString* name = [NSString stringWithUTF8String:countryName];
I know what the rest does (I only had to google how to do this part), it is supposed to take my char* (countryName) and turn it into an NSString so later on I can compare it with the
isEqualToString:
thing. I would just like to know what the following is actually doing to the char, and what does the UTF8String even mean?
I have barely any Objective C programming experience so any feedback is helpful :D
you are not totally right.
this method
Returns a string created by copying the data from a given C array of UTF8-encoded bytes.
so, UTF-8 string here is just a C array of bytes.
Check the documentation here.
It doesn't do anything to the char * string. It's just the input to the method. stringWithUTF8String takes a C-style string (in UTF-8 encoding), and creates an NSString using it as a template.
This is my main:
int x=0;
NSString *new=[[NSString alloc]initWithString:#"9+4"];
x=[new intValue];
NSLog(#"hi %i",x);
This results in 9.. .since giving the intValue of a string will read only numbers and stops when the character is not a digit.
So how can i print the result of my string and get a 13 instead??
Actually, NSExpression was made just for this:
NSExpression *expression = [NSExpression expressionWithFormat:#"9+4"];
// result is a NSNumber
id result = [expression expressionValueWithObject:nil context:nil];
NSLog(#"%#", result);
NSExpression is very powerful, I suggest you read up on it. You can use variables by passing in objects through the format string.
Change this line
NSString *new=[[NSString alloc]initWithString:#"9+4"];
to
NSString *new=[NSString stringWithFormat:#"%f",9+4];
You will have to manually parse it. You could write a subclass of NSString that overrides the intValue method, and parses it to find arithmetic symbols and perform the math, but thats as close to automatic as you're gonna get I'm afraid
You will need to parse and evaluate it yourself, as seemingly simple calculations like this are beyond the scope of the basic string parsing Apple provides you. It might seem to be a no-brainer if you're used to interpreted languages like Ruby, Perl and the like. But for a compiled language support for runtime evaluation of expressions are uncommon (there are languages that do support them, but Objective-C is not one of them).
When attempting to parse an expression in a string you will want to use Reverse Polish Notation. Here is the first example I cam across in a google search for Objective-C.
I have a Mac application that keeps it's own log file. It appends info to the file using NSString's writeToFile method. One of the things that it logs are URL's of web services that it is interacting with. To encode the URL, I'm doing this:
searchString = (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL, (CFStringRef)searchString, NULL, (CFStringRef)#"!*'();:#&=+$,/?%#[]", kCFStringEncodingUTF8 );
The app then appends searchString to the rest of the URL and writes it to the log file. Now the problem is that after adding that URL encoding line, nothing seems to be getting written to the file. The program functions as expected otherwise however. Removing the line of code above results in all of the correct information being logged to the file (removing that line is not an option because searchString must be URL encoded).
Oh and I am using NSUTF8StringEncoding when writing the NSString to the file.
Thanks for any help.
EDIT: I know there's also a similar function to CFURLCreateStringByAddingPercentEscapes in NSString, but I've read that it doesn't always work. Can anyone shed some light on this if my original question cannot be answered? Thanks! (EDIT: same problem occurs when using stringByAddingPercentEscapesUsingEncoding:)
EDIT 2: Here's the code that I'm using to append messages to the log file.
+(void)logText:(NSString *)theString{
NSString *docsDirectory = [NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory,NSUserDomainMask,YES) objectAtIndex:0];
NSString *path = [docsDirectory stringByAppendingPathComponent:#"Folder/File.log"];
NSString *fileContents = [[[NSString alloc] initWithContentsOfFile:path] autorelease];
if([fileContents lengthOfBytesUsingEncoding:NSUTF8StringEncoding] >= 204800){
fileContents = #"";
}
NSString *timeStamp = [[NSDate date] description];
timeStamp = [timeStamp stringByAppendingString:#": "];
timeStamp = [timeStamp stringByAppendingString:theString];
fileContents = [fileContents stringByAppendingString:timeStamp];
fileContents = [fileContents stringByAppendingString:#"\n"];
[fileContents writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:NULL];
}
Because after almost a whole day no one else has offered any answers, I'm going to post a wild guess here: you're not accidentally using the string you want to output (with percent characters in it) as a format string are you?
That is, making the mistake of doing:
NSLog(#"In format strings you can use %# as a placeholder for an object, and %i for a plain C integer.")
Instead of:
NSLog(#"%#", #"In format strings you can use %# as a placeholder for an object, and %i for a plain C integer.");
But I'm going to be surprised if this turns out to be the cause of your problem, as it usually causes random-looking output, rather than absolutely no output. And in some cases, Xcode also gives compiler warnings about it (when I tried NSLog(myString), I got "warning: format not a string literal and no format arguments").
So don't shoot me down if this answer doesn't help. It would be easier to answer your question if you could show us more of your logging code. As for the one line you provided, I can't detect anything wrong with it.
Edit: Oops, I kind of missed that you mentioned you're using writeToFile:atomically:encoding:error: to write the string to the file, so it's even more unlikely you're accidentally treating it as a format string somewhere. But I'm going to leave this answer up for now. Again, you should really show us more of your code though ...
Edit: Regarding your question on a method in NSString that has similar percent encoding functionality, that would be stringByAddingPercentEscapesUsingEncoding:. I'm not sure what kind of problems you're thinking of when you say you've heard it doesn't always work. But one thing is that CFURLCreateStringByAddingPercentEscapes allows you to specify extra characters that don't normally have to be escaped but which you still want to be escaped, while the method of NSString doesn't allow you to specify this.
I was following a tut and found a line of code like #"%# button pressed.". I'm pretty sure the relevant part is the %#, but is the first # an escape sequence or what?
Anyways, searching symbols doesn't go well in any search engine so I thought I'd ask. I think the %# is like {0} in C#?
%# is a format specifier. Functions such as NSLog and methods such as +stringWithFormat: will replace %# with the description of the provided Objective-C or Core Foundation object argument.
For example:
NSString *myName = #"dreamlax";
NSLog (#"My name is: %#", myName);
This will log the output "My name is: dreamlax". See here for more information format specifiers.
The initial # symbol at the beginning of the string tells the compiler to create a static instance of an NSString object. Without that initial # symbol, the compiler will create a simpler C-style string. Since C-style strings are not Objective-C objects you cannot add them to NSArray or NSDictionary objects, etc.
#"some string" means this is an NSString literal.
The string as show in #"CupOverflowException", is a constant
NSString object. The # sign is used
often in Objective-C to denote
extentions to the language. A C string
is just like C and C++, "String
constant", and is of type char *
I found this page which might help - http://www.yetanotherchris.me/home/2009/6/22/objective-c-by-example-for-a-c-developer.html
It seems that you are on the right track.
I'm still fairly new to the language, but it looks like the # specifies that the variable being passed/created is an NSObject, or a compiler directive.
As mentioned above, if you use it like this:
#"someText"
you're instantiating an NSString object, and setting the text of that object to someText. If you look at a good ol' C-style format specifier such as:
..."This is some text, and this is a float: %f", myFloat);
You're creating some text and telling the compiler to put the floating point string representation of myFloat into the string. %# is a format specifier, just like %f, %d, %c, %s and any other format specifier you're used to. However, if you use %# as follows:
... "This is some text, and this is an object:%#", myObject];
What you're doing is (I believe) telling the compiler that myObject is an object, and that you want it to include the output of the description method (ie. [myObject description]) in the string that you're creating.