Objective-C URL string contains single percent sign - objective-c

I have a string which ends with percent sign(%),
this string is prepared for an URL request as a parameter:
NSString *parameter = #"/param=%";
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL urlWithString:[NSString stringWithFormat:#"http://www.whatev%#",parameter]]];
The request returns nil.
I've tried:
NSString *parameter = #"/param=\uFF05";
//request returns nil
and
NSString *parameter = #"/param=%";
NSString *newParameter = [parameter stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
//request returns /param=%25 ...where does 25 come from?!
How could I have only one % converted to a request url?
Any advice would be appreciated.

The percent sign has a special purpose in URL's and is used to encode special characters of all kinds. For example a space ( ) is %20 and the percent sign itself is %25.
http://en.wikipedia.org/wiki/Percent-encoding
The last one should be correct, I assume you have problems using it as a request?

escape sequence for % is %%, so #"/param=%%" should solve the problem

Related

iOS NSURL returning nil on valid URL

I've entered the URL http://localhost:8080/a?a=1\\tb?b=2 on the Safari it worked as expected but when using NSURL URLWithString it return nil.
(The server also require \t character)
NSURL *url = [NSURL URLWithString:#"http://localhost:8080/a?a=1\\tb?b=2"];
The problem is that you need to percent-encode your values in the URL string. When it’s received by the server, it will decode this percent-encoded string in the URL into the desired value.
But rather than percent-encoding yourself, you can use NSURLComponents. For example, if you want a to have the value of #"1\\tb", you can do:
NSURLComponents *components = [NSURLComponents componentsWithString:#"http://localhost:8080"];
components.queryItems = #[
[NSURLQueryItem queryItemWithName:#"a" value:#"1\\tb"],
[NSURLQueryItem queryItemWithName:#"b" value:#"2"]
];
NSURL *url = components.URL;
Yielding:
http://localhost:8080?a=1%5Ctb&b=2
Or, if you wanted it to have the tab character in the value associated with a (i.e. %09):
NSURLComponents *components = [NSURLComponents componentsWithString:#"http://localhost:8080"];
components.queryItems = #[
[NSURLQueryItem queryItemWithName:#"a" value:#"1\tb"],
[NSURLQueryItem queryItemWithName:#"b" value:#"2"]
];
NSURL *url = components.URL;
Yielding:
http://localhost:8080?a=1%09b&b=2
It just depends upon whether your server is expecting two characters, the \ followed by t (the first example) or the single \t character (the second example). Either way, the respective use of NSURLComponents will take care of the percent-encoding for you, and your server will decode it.
For what it’s worth, the one caveat is the + character, which NSURLComponents won’t percent-encode for you (because, technically, a + character is allowed in a URL query). The problem is that the + character is interpreted as a space character by most web servers (per the x-www-form-urlencoded spec). If you need to pass a literal + character, you might want to replace those + characters, as advised by Apple:
NSURLComponents *components = [NSURLComponents componentsWithString:#"http://localhost:8080"];
components.queryItems = #[
[NSURLQueryItem queryItemWithName:#"q" value:#"Romeo+Juliet"]
];
components.percentEncodedQuery = [components.percentEncodedQuery stringByReplacingOccurrencesOfString:#"+" withString:#"%2B"];
NSURL *url = components.URL;

How to Use An Escape URL String With Formatting in Objective-C

I need to gather data from a website based on the user's input.
searchString is the user inputted value, such as "search this string".
NSString *withoutSpaces = [searchString stringByReplacingOccurrencesOfString:#" " withString:#"%20"];
Here, I need to replace spaces with %20
Next, I need to put the new string without spaces (replaced with %20) into another string.
NSString *unescapedSearchString = [NSString stringWithFormat:
#"website.com/query?=%22%#%22", withoutSpaces];
The site I need is not really "website.com", but that's just an example. I also need the %22 to remain at the beginning and end.
As you can see, I need the %# to format the new withoutSpaces user input into the website URL.
I did a search and found examples but I could not find any with formatting such as in my case using %#.
What's the best way to "escape" the characters and keep my formatted string? Currently, when I try to access data from the website, it comes back as null. However, when I try a string without the %# formatting and an actual value, I successfully retrieve the data from a website.
Any help is greatly appreciated.
You should do things this way:
NSString *searchString = ... // the raw search string with spaces and all
NSString *quoted = [NSString stringWithFormat:#"\"%#\"", searchString];
NSString *escaped = [quoted stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *urlString = [NSString stringWithFormat:#"website.com?query=%#&value=all", escaped];
BTW - the URL seems a little off. There should be a variable name before the = and after the ?.

URL from string gives null

I have a string which gives the path, and another which appends the parameters to it. When i put them in a string and display, I'm getting in the correct format. If i try to put the entire string in NSURL, it displays NULL.
What is the format to get it?
NSString *booking=urlForBooking.bookHall;
NSLog(#" book %#",booking); // this prints --- http://10.2.0.76:8080/ConferenceHall/BookingHallServlet
NSString *bookingString=[booking stringByAppendingString:[NSString stringWithFormat:#"? employeeId=%#&conferenceHallId=%#&bookingId=%d&purpouse=%#&fromDate=%#&toDate=%#&comments=%#&submit=1",empId,_hallId,_bookingId,_purpose,fromDateStr,toDateStr,_comments]];
NSLog(#"book str %#",bookingString); //this prints --- ?employeeId=3306&conferenceHallId=112&bookingId=0&purpouse=S&fromDate=25/Feb/2013 13:29&toDate=25/Feb/2013 15:29&comments=C&submit=1
NSURL *bookingURL=[NSURL URLWithString:bookingString];
NSLog(#"BOOK %#",bookingURL); //here I'm not getting the url(combined string), it gives null.
That is because the URL your are building contains charters that are not valid in an URL, like spaces and slashes.
You should escape these characters:
NSString *bookingPath =[bookingString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *bookingURL=[NSURL URLWithString:bookingPath];
You might need to replace the slashes in the date because they might not be encoded correctly.
NSString *bookingString=[NSString stringWithFormat:#"%#?employeeId=%#&conferenceHallId=%#&bookingId=%d&purpouse=%#&fromDate=%#&toDate=%#&comments=%#&submit=1",
booking,
empId,
_hallId,
_bookingId,
[_purpose stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],
[fromDateStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],
[toDateStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],
[_comments stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSURL *bookingURL=[NSURL URLWithString:bookingString];
NSLog(#"BOOK %#",bookingURL);
Your URL string is incorrect in some way, and as such is getting parsed to nil. The documentation for NSURL tells you this can happen:
Return Value An NSURL object initialized with URLString. If the string
was malformed, returns nil.
You shouldn't have all those leading spaces after the ? portion of your URL, and the entire thing needs to be escaped prior to parsing it into a URL.
The spaces in _ bookingString_ (before employeeId and in the date) kill your URL.

encode a nsstring with utf-8Type for post connection

Trying to postdata in post connection using setHttpPost
NSString* strRequest = [NSString stringWithFormat:#"username=%#&password==%#&client_assertion_type=%#&client_assertion=%#&spEntityID=%#",
strUsrName,strPasswrd,#"JWT",strAppTknContent,#"http://localhost:8080/opensso"];
NSData* dataRequest = [NSData dataWithBytes:[strRequest UTF8String] length:[strRequest length]];
[theRequest setHTTPMethod: #"POST"];
[theRequest setHTTPBody: dataRequest];
want to encode the value for username,password,client_assertion_type alone utf-8 type
NSString* username = [ encode utf-8 type #"fff"];
how do i encode only the value of each key elements and post it
You cannot encode a string in UTF-8 and then put it in a NSString instance. NSString uses Unicode characters anyway but not in an encoded form.
Why would you want to encode them separately anyway? What exactly are you trying to achieve?
And just to point out a mistake in your code. The following line does not work once you have characters that require more than 1 byte in UTF-8:
NSData* dataRequest = [NSData dataWithBytes:[strRequest UTF8String] length:[strRequest length]];
The length parameter is expected to be the number of bytes but you are passing the number of characters.
A correct and simpler alternative is:
NSData* dataRequest = [strRequest dataUsingEncoding: NSUTF8StringEncoding ];
Update:
As you obviously want to properly URL encoded your parameters, you're probably looking for code like this:
NSString* strRequest = [NSString stringWithFormat:#"username=%#&password==%#&client_assertion_type=%#&client_assertion=%#&spEntityID=%#",
[strUsrName stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],
[strPasswrd stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],
#"JWT",
[strAppTknContent stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],
[#"http://localhost:8080/opensso" stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]
];
NSData* dataRequest = [strRequest dataUsingEncoding: NSUTF8StringEncoding ];
Update 2:
It's a very strange design to transmit data that way. When it was first used, it probably was a hack to get something working quickly. Unfortunately, it became a standard.
Basically, you have two levels of encoding. The URL encoding to serves to put several key/value pairs into a single string such that the string can later be split again into the key/value pairs. It needs to know that a UTF-8 encoding is used on the second level so it can escape the problematic characters. It's does UTF-8 the string yet.
The second level translates the string (a sequence of characters) into a byte stream using the UTF-8 encoding since HTTP is specified as a transmission of bytes, not characters.

objective C NSString stringwithformat of a URL

i need my application to send an HTTP request to my server, this is the link, but for some reason, when i create an NSString stringwithformat not all of the string is copied into the string,
this is my URL:
http://192.168.50.204:8080/webapi/originate?sofia/internal/408%25192.168.50.204%20'set:effective_caller_id_number=722772408,bridge:sofia/gateway/012smile/<PHONENUMBER>#212.199.220.21'%20inline%200545890183%200545890183
if i put it in my browser it is working fine.
and this is the code:
self.feedURLString = [NSString stringWithFormat:#"http://192.168.50.204:8080/webapi/originate?sofia/internal/%#%25192.168.50.204%20'set:effective_caller_id_number=722772%#,bridge:sofia/gateway/012smile/%##212.199.220.21'%20inline%20%#%20%#",extention,extention,PhoneNumber,PhoneNumber, PhoneNumber];
keep in mind that there are some %20 and %25 in the URL, maybe it causes the problem...
the string i get in the NSLog is:
feedURLString = http://192.168.50.204:8080/webapi/originate?sofia/internal/408220'set:effective_caller_id_number=722772408,bridge:sofia/gateway/012smile/0545890183#212.199.220.21' 93610576nline2#2#
remove the %20 and %25 from the string
then use the stringByAddingPercentEscapesUsingEncoding command from NSString
string = [sURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
You're right, the %20 are almost certainly causing a problem.
Any places in the string you want an actual % symbol in the result, you should be writing %%.
Another option that some people use is to leave the %s as they are, but use stringByReplacingOccurrencesOfString:withString: to do the substitiation.
eg:
NSString *str = #"http://{HOST}/{USER}/blah";
str = [str stringByReplacingOccurrencesOfString:"{HOST}" withString:hostname];
str = [str stringByReplacingOccurrencesOfString:"{USER}" withString:username];
Try writing the url with the normal characters instead of %20 and %25, then add in your variables, and when you have the complete url string use
[feedURLString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEndocing];
Edit: sorry for double, I guess the anwser was obvious :)