NSString stringByReplacingPercentEscapesUsingEncoding doesn't work - objective-c

I need to get url string from NSString. I do the following:
NSString * str = [NSString stringWithString:#"i#gmail.com"];
NSString * eStr = [str stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(#"%#",eStr);
The result is i#gmail.com. But I need i%40gmail.com. replacing NSUTF8StringEncoding with NSASCIIStringEncoding doesn't help.

You're using the wrong method. This does the opposite, translating percent
escapes to their characters. You probably want to use
stringByAddingPercentEscapesUsingEncoding:.
NSString *str = #"i#gmail.com";
NSString *eStr =
[str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
Apart from that, looks like the # character is not escaped by default. Then,
as the documentation for the above method points out, you'll need to use
CoreFoundation to achieve what you want.
NSString *str = #"i#gmail.com";
CFStringRef eStr = CFURLCreateStringByAddingPercentEscapes(
kCFAllocatorDefault,
(CFStringRef)str,
NULL,
(CFStringRef)#"#",
kCFStringEncodingUTF8
);
NSLog(#"%#", eStr);
CFRelease(eStr);
Please check the documentation to know more about the function used and
how to make it fit your needs.

Related

How to leave a set number of spaces in NSString?

I have separate text objects for the unchanging portion (i.e. "Bonus Score: (+7%)") and the changing portion (e.g. "247,890"). Since they're separate, I want to leave space in the unchanging portion to display the number.
What I first tried was:
NSString* numberString = #"247,890";
NSString* blankScore = [#"" stringByPaddingToLength:[numberString length] withString: #" " startingAtIndex:0];
NSString* baseDisplay = [NSString stringWithFormat:#"BONUS SCORE: %# (+7%%)", blankScore];
'blankScore' was the correct length, but the resulting baseDisplay seemed to trim the spaces around where blankScore would be, making it too small of a space for the displayed number.
Next I tried another way of creating blankScore:
NSString* blankScore = [numberString stringByReplacingCharactersInRange:NSMakeRange(0, [numberString length]) withString:#" "];
But this returned a blankScore of length 1.
Am I understanding these NSString methods incorrectly? I checked the docs, and it seems like my understanding of these methods aligns with what's written there, but I still don't understand why I can't get my baseDisplay to have the correct number of spaces.
Have you printed blankScore on the console using NSLog? Actually your string is correct, but the output is trimmed at end of lines - this is why you see it as described.
#H2CO3 is on to the right solution. You should be using:
NSString *baseDisplay = [NSString stringWithFormat:#"BONUS SCORE: %# (+7%%)", numberString];
To make this work even better, you may want to consider an NSNumberFormatter to correctly format the changing part before inserting it into the baseDisplay object. Something like this:
NSNumber *changingNumber = [NSNumber numberWithDouble:247890];
NSNumberFormatter *correctFormat = [[NSNumberFormatter alloc] init];
[correctFormat setNumberStyle:NSNumberFormatterDecimalStyle];
[correctFormat setHasThousandSeparators:YES];
[correctFormat setUsesGroupingSeparator:YES];
NSString *numberString = [correctFormat stringFromNumber:changingNumber];
NSString *baseDisplay = [NSString stringWithFormat:#"BONUS SCORE: %# (+7%%)", numberString];
This way no matter what number you throw at it, it will correctly display "1,234,456" or "34,567", whatever.
EDIT:
Based on the comments to my answer you will need to use:
stringByPaddingToLength:withString:startingAtIndex:
It should look something like this:
NSString *templateString = #"BONUS SCORE:";
NSString *templateString2 = #"(+7%%)";
NSUInteger baseStringLength = [templateString length] + [numberString length];
NSString *spacedString = [templateString stringByPaddingToLength:baseStringLength withString:#" " startingAtIndex:0];
NSString *baseDisplay = [NSString stringWithFormat:#"%#%#", spacedString, templateString2];

How do I include an # sign within an NSString literal?

Searched around and didn't see an obvious answer. Thanks in advance.
I simply want to append an # sign at the end of an NSString.
This will work:
NSString *myConstString = #"john#example.com";
And this will, too:
NSString *aString = ...;
NSString *myString = [aString stringByAppendingString: #"#"];
# is just a character which doesn't need escaping.

NSString: changing a filename but not the extension

Times like this and my Objective-C noobness shows. :-/
So, the more I work on a routine to do this, the more complex it's becoming, and I'm wondering if there isn't just a simple method to change the name of a filename in a path. Basically, I want to change #"/some/path/abc.txt to #"/some/path/xyz.txt -- replacing the filename portion but not changing the path or extension.
Thanks!
Try the following:
NSString* initPath = ...
NSString *newPath = [[NSString stringWithFormat:#"%#/%#",
[initPath stringByDeletingLastPathComponent], newFileName]
stringByAppendingPathExtension:[initPath pathExtension]];
What Vladimir said, just broken down more to make it a little easier to read:
NSString *pathToFile = #"/Path/To/File.txt";
NSString *oldFileName = [pathToFile lastPathComponent];
NSString *newFileName = [#"Document" stringByAppendingPathExtension:[oldFileName pathExtension];
NSString *newPathToFile = [pathToFile stringByDeletingLastPathComponent];
[newPathToFile stringByAppendingString:newFileName];
Take a look at the "Working With Paths" section of the NSString docs. In particular, lastPathComponent, pathExtension and stringByDeletingPathExtension: should do what you want.
You can try something like this:
NSRange slashRange = [myString rangeOfString:#"\\" options:NSBackwardsSearch];
NSRange periodRange = [myString rangeOfString:#"." options:NSBackwardsSearch];
NSString *newString = [myString stringByReplacingCharactersInRange:NSMakeRange(slashRange.location, periodRange.location) withString:#"replacement-string-here"];
What this code does is it gets the location of the \ and . characters and performs a backwards search so that it returns the last occurrence of it in the string.
Then, it creates a new range based on those previous ranges and replaces the contents in that range with stringByReplacingCharactersInRange:.
Try this:
NSString* path = [startString stringByDeletingLastPathComponent];
NSString* extension = [startString pathExtension];
NSString* replacementFileName = [#"foo" stringByAppendingPathExtension: extension];
NSString result = [path stringByAppendingPathComponent: replacementFileName];

Get a string with ascii code objective-c

I have a ascii code, for the letter 'a', and I want to get a string by its ascii code, is it possible with NSString?
This could also work:
NSString *foo = [NSString stringWithFormat:#"%c", 97];
Didn’t test it.
If you mean you have a byte that represents an ASCII-encoded character and you want to make a string out of it, NSString has an initializer just for that.
char characterCodeInASCII = 97;
NSString *stringWithAInIt = [[NSString alloc] initWithBytes:&characterCodeInASCII length:1 encoding:NSASCIIStringEncoding];

Merge 5 NSStrings in Objective-C

I have multiple NSStrings and i wish to merge them into one other, here is my code so far...
NSString *newURL = [_parameters objectForKey:#"url"];
NSString *emailBody = #"Hey!<br>I just snipped my long url with My Cool App for iPhone in just a few seconds!<p><b>"+newURL+#"</b></p>";
If you know the number of your existing strings, you can just concat them:
NSString* longString = [firstString stringByAppendingString:secondString];
or:
NSString* longString = [NSString stringWithFormat:#"A string: %#, a float: %1.2f", #"string", 31415.9265];
If you have an arbitrary number of strings, you could put them in an NSArray and join them with:
NSArray* chunks = ... get an array, say by splitting it;
NSString* string = [chunks componentsJoinedByString: #" :-) "];
(Taken from http://borkware.com/quickies/one?topic=NSString)
Another good resource for string handling in Cocoa is: "String Programming Guide"
You can try
NSString *emailBody = [ NSString stringWithFormat: #"Hey!<br>I just snipped my long url with Snippety Snip for iPhone in just a few seconds, why not check it out?<p><b>%#</b></p>", newURL ];
Given that you've got multiple strings I recommend using an Array:
NSArray *array = [NSArray arrayWithObjects:#"URL", #"person", "body"];
NSString *combined = [array componentsJoinedByString:#""];
Formatting string has better readability and less error-prone:
NSString *newURL = [_parameters objectForKey:#"url"];
NSString *emailBody = [NSString stringWithFormat:#"Hey!<br>I just snipped my long url with Snippety Snip for iPhone in just a few seconds, why not check it out?<p><b>%#</b></p>", newUrl, newUrl];
You can concatenate strings in Cocoa using:
[NSString stringByAppendingString:]
Or you could use the [NSString stringWithFormat] method which will allow you to specify a C-style format string with a variable argument list to populate the escape sequences.