My app calls a web service to login. Usually the service works without any problems, but when I've a password with a special characters (example: !*'\"();:#&=+$,/?%#[]%), the web server doesn't allow me to login because on server side I receive the password without special characters for example:
password insert on my app: test+test
password receive to web server: testtest
As you see the request delete the special characters actually I'm sending the login credential by using the following code:
- (id)sendRequestToURL:(NSString *)url withMethod:(NSString *)method withUsername:(NSString*)username withPassword:(NSString*)password andInstallationId:(NSString*)installationId {
NSURL *finalURL = [[NSURL alloc]init];
if ([method isEqualToString:#"POST"]) {
finalURL = [NSURL URLWithString:url];
} else {
NSLog(#"Metodo no previsto");
}
NSString *post = [NSString stringWithFormat:#"username=%#&password=%#&installationId=%#", username, password, installationId];
NSData *postData = [post dataUsingEncoding:NSUTF8StringEncoding];
NSString *postLength = [NSString stringWithFormat:#"%lu", (unsigned long)postData.length];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]init];
[request setURL:finalURL];
[request setHTTPMethod:method];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];
if (connection) {
[connection start];
}
return connection;
}
How I can fix this issue? I looked at the NSString class reference, I saw there's the method - stringByAddingPercentEncodingWithAllowedCharacters: to don't delete the special characters, does anyone know how to use this method? Can you show me a code snippet?
Thank you
I found a way to solve this issue, below is my code, maybe it should be useful for someone:
- (id)sendRequestToURL:(NSString *)url withMethod:(NSString *)method withUsername:(NSString*)username withPassword:(NSString*)password andInstallationId:(NSString*)installationId {
NSURL *finalURL = [[NSURL alloc]init];
if ([method isEqualToString:#"POST"]) {
finalURL = [NSURL URLWithString:url];
} else {
NSLog(#"Metodo no previsto");
}
NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString:#"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLKMNOPQRSTUVWXYZ0123456789"];
NSString *encodedPassword = [password stringByAddingPercentEncodingWithAllowedCharacters:set];
NSString *post = [NSString stringWithFormat:#"username=%#&password=%#&installationId=%#", username, encodedPassword, installationId];
NSData *postData = [post dataUsingEncoding:NSUTF8StringEncoding];
NSString *postLength = [NSString stringWithFormat:#"%lu", (unsigned long)postData.length];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]init];
[request setURL:finalURL];
[request setHTTPMethod:method];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];
if (connection) {
[connection start];
}
return connection;
}
In this way I search in the password string the special characters and if it found it change this character with the percent encoding. In that way I can log in with plain password and with password with special characters. I hope it will be useful for someone.
Just encode every parmeter with the - stringByAddingPercentEscapesUsingEncoding:.
NSString *encodeUsername = [username stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *encodePassword = [password stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *encodeInstallationId = [installationId stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *post = [NSString stringWithFormat:#"username=%#&password=%#&installationId=%#", encodeUsername, encodePassword, ins encodeInstallationId allationId];
And use this encoded paramater in your request.
Url encode your string and POST to web service. Please use below method for url encoding.
+(NSString *) urlencode: (NSString *) str {
NSString * encodedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(
NULL,
(CFStringRef)str,
NULL,
(CFStringRef)#" ",
kCFStringEncodingUTF8 );
return [encodedString autorelease];
}
Related
I am new to IOS i need to pass three parameter in POST method.my parameter are (1)str (2)str1 (3)str2.this three parameter are fetch from different url in string format.
coding for POST method:
i need to add these parameter in method?i already added str parameter but i am struggling to pass other two(str1,str2) parameter.
-(void) sendDataToServer : (NSString *) method params:(NSString *)str{
NSString *post = [NSString stringWithFormat:#"branch_id=%#",str];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%lu", (unsigned long)[post length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:URL]];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody:postData];
NSURLConnection *theConnection = [NSURLConnection connectionWithRequest:request delegate:self];
if( theConnection ){
mutableData = [[NSMutableData alloc]init];
}
}
Viewdidload:
here also i want to str1 and str2 parameter.
[self sendDataToServer :#"POST" params:str];
you can implement in multiple ways
Choice-1
-(void) sendDataToServer : (NSString *) method firstparams:(NSString *)firststr secondparam:(NSString *)secondstr thirdparam:(NSString *)thirdstr{
NSString *post = [NSString stringWithFormat:#"branch_id=%#&xxxx=%#&yyyyy=%#",firststr,secondstr,thirdstr];
// continue your works as its same flow
call method like
[self sendDataToServer :#"POST" firstparams:#"yourbranchID" secondparam:#"xxxValue" thirdparam:#"yyyyvalue"];
Choice-2
what ever you did is correct, just modify some code in viewdidload or else
// add all values in one string using stringWithFormat
NSString *str = [NSString stringWithFormat:#"branch_id=%#&xxxx=%#&yyyyy=%#",firststr,secondstr,thirdstr];
// and pass the param to web call
[self sendDataToServer :#"POST" params:str];
call method as
-(void) sendDataToServer : (NSString *) method params:(NSString *)str{
// no need of this line
// NSString *post = [NSString stringWithFormat:#"branch_id=%#",str];
// directly called the str in her
NSData *postData = [str dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%lu", (unsigned long)[post length]];
/.... as its is continue the same work
instead of passing it as NSString just add the three string in a globally declared array and add objects to it and send it to web service.
or create them as NSDictionary and convert them as json string to web service.
NSDictionary *params = #{#"param1": str1, #"param2": str2, #"param3": str3 };
[self sendDataToServer :#"POST" params:params];
-(void) sendDataToServer : (NSString *) method params:(NSDictionary *)dict
{
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict
options:NSJSONWritingPrettyPrinted // Pass 0 if you don't care about the readability of the generated string
error:&error];
if (! jsonData) {
NSLog(#"Got an error: %#", error);
} else {
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:URL]];
[request setHTTPMethod:#"POST"];
[request setValue:jsonString forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody:jsonData];
NSURLConnection *theConnection = [NSURLConnection connectionWithRequest:request delegate:self];
if( theConnection ){
mutableData = [[NSMutableData alloc]init];
}
}
}
I am developing an iOS app which required to send phone number on server.
When I pass number without "+" it is work fine, but when I pass number with "+" sign (+123456, +234567) then it send number like (" 123456"," 234567").
It replace "+" by " " (space).
I convert NSDictionary into JsonData .
NSError *err;
NSData *data=[NSJSONSerialization dataWithJSONObject:mdict options:0 error:&err];
NSString *str=[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
NSString *strjson=[NSString stringWithFormat:#"GetData=%#",str];
NSLog(#"strjson=%#",strjson);
My code to build NSMutableRequest object.
NSURL *url = [NSURL URLWithString:urlString];
__weak NSString *postLength = [NSString stringWithFormat:#"%lu", (unsigned long)[soadMessage length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody:[soadMessage dataUsingEncoding:NSUTF8StringEncoding]];
[request addValue: #"application/x-www-form-urlencoded; charset=utf-8" forHTTPHeaderField: #"Content-Type"];
_connection = [[NSURLConnection alloc]initWithRequest:request delegate:self];
[_connection start];
Any help will be appreciated.
Try to escape your string with the CFURLCreateStringByAddingPercentEscapes
+ (NSString *)escapeValueForURLParameter:(NSString *)valueToEscape {
if (![valueToEscape isKindOfClass:[NSString class]]) {
valueToEscape = [(id)valueToEscape stringValue];
}
return (__bridge_transfer NSString *) CFURLCreateStringByAddingPercentEscapes(NULL, (__bridge CFStringRef) valueToEscape,
NULL, (CFStringRef) #"!*'();:#&=+$,/?%#[]", kCFStringEncodingUTF8);
}
You need to format the value of mdict to take out the + character. Or you could also trim it from the JSON at the end. Either way you will get the desired result.
Something like this:
mdict["Phone"].value = [mdict["Phone"].value stringByReplacingOccurrencesOfString:#"+"
withString:#""];
This is pseudocode but you get the idea. After doing this you can do the serialization and it should be fine.
Currently I have a string that I want to POST to a URL.
It works perfectly fine except when it encounters special characters like "&", and "?". It will not POST any data that comes after that. For example, if I have a string "I am something & something?", it will only POST "I am something". As for "?", it will be converted to '2' after it has been posted.
reason = 'What see see! Are you sure'2''
I am pretty sure that it must have something to do with encoding as I can see "I am something & something?" as it is just before I set the encoding:
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding];
I have also tried the encodings below with no success:
NSData *postData = [post dataUsingEncoding:NSUTF8StringEncoding];
NSData *postData = [post dataUsingEncoding:NSNonLossyASCIIStringEncoding];
NSData *postData = [post dataUsingEncoding:NSISOLatin1StringEncoding];
Below are my codes from postData onwards:
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding];
//NSLog(#"PostData: %#", postData);
NSString *check = [[NSString alloc] initWithData:postData encoding:NSASCIIStringEncoding];
NSLog(#"check string = %#", check);
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:strURLQueryString]];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody:postData];
NSURLResponse *response;
NSError *err=nil;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
NSString *strResponse = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSLog(#"Response: %#", strResponse);
if(err!=nil) {
NSLog(#"Error: %#", [err description]);
}
Please assist.
Your help(s) are appreciated.
There's probably a better answer out there somewhere, but this class extension has been working for me for awhile. I cobbled together the % escapes by looking at a few posts...
// NSString+URLEncoding.h
#interface NSString (NSString_URLEncoding)
- (NSString *)urlEncodeUsingEncoding:(CFStringEncoding)encoding;
- (NSString *)urlEncode;
#end
// NSString+URLEncoding.m
#implementation NSString (NSString_URLEncoding)
- (NSString *)urlEncodeUsingEncoding:(CFStringEncoding)encoding {
return CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
(__bridge CFStringRef)self,
NULL,
CFSTR("!*'();:#&=+$,/?%#[]"),
encoding));
}
- (NSString *)urlEncode {
return [self urlEncodeUsingEncoding:kCFStringEncodingUTF8];
}
Then in somer other class to send a string...
// SomeOtherClass.m
#import "NSString+URLEncoding.h"
NSString *encodedString = [#"This & this? are 'challenging' to !% encode" urlEncode];
I am stuck with an issue in simple request response in iOS, I am getting blank response in request a url with one post parameter, where the url as it is perfectly working in android and webbrowser
Friends in detail, I have to call
http://example.com/GetCountries
with below http post params
"key"="Abcd1234"
it is working before, but from last few days it is not working, if I check NSError it is showing me The network connection was lost.
and one more thing noticeable here is same server code is on different url and it is working fine, and that url you can test as below
http://example.com/GetCountries
with below http post params
"key"="Abcd1234"
Here is the dropbox link for testing ios source code and also the folder contains Web services test.htm file to test that same url with same post parameter working in browser but not in ios device.
Testing code:
https://dl.dropboxusercontent.com/s/lqrl5b95j2s54mm/Testing.zip?token_hash=AAFgoNfUpQ4FkeswnPdGiMVzdMtSM6js9KySJm_OH6lZXQ&dl=1
thank you
So I could not get the form per se to work but was able to recraft it to work. Note a few things:
you should convert to ARC!
you need a strong reference to the connection so you can release it later on (and not in a delegate method!)
you need the delegate connectionSucceeded method (to record response whatever!)
CODE:
- (void)asynchronousRequest
{
[activity startAnimating];
NSString *requesturl = lblURL.text;
NSLog(#"requesturl=%#", requesturl);
NSURL *theURL = [NSURL URLWithString:requesturl];
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
[request setValue:#"application/x-www-form-urlencoded; charset=utf-8" forHTTPHeaderField:#"content-type"];
[request setURL:theURL];
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
[request setTimeoutInterval:60.0];
[request setHTTPMethod:#"POST"];
NSString *str = [NSString stringWithFormat:#"key=%#", [self URLencodedString:#"Abcd1234"]];
NSLog(#"BODY: %#", str);
NSData *body = [str dataUsingEncoding:NSUTF8StringEncoding];
NSLog(#"URL : %#", requesturl);
NSLog(#"REQ : %#", request);
[request setHTTPBody:body];
[request addValue:[NSString stringWithFormat:#"%u", [body length]] forHTTPHeaderField:#"Content-Length"];
NSLog(#"AllFields : %#", [request allHTTPHeaderFields]);
NSLog(#"HTTPBody : %#", [[NSString alloc] initWithData:[request HTTPBody] encoding:NSUTF8StringEncoding]);
NSLog(#"HTTPMethod : %#", [request HTTPMethod]);
self.activeDownload = [NSMutableData data];
conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
assert(conn);
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
assert([response isKindOfClass:[NSHTTPURLResponse class]]);
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
NSLog(#"GOT %d", [httpResponse statusCode]);
}
- (NSString *)URLencodedString:(NSString *)s
{
CFStringRef str = CFURLCreateStringByAddingPercentEscapes(NULL, (CFStringRef)s, NULL, (CFStringRef)#"!*'();:#&;=+$,/?%#[]", kCFStringEncodingUTF8);
NSString *newString = [(NSString *)str stringByReplacingOccurrencesOfString:#" " withString:#"+"];
if(str) CFRelease(str);
return newString;
}
EDIT: Modified Code that still didn't work:
- (void)asynchronousRequest
{
[activity startAnimating];
NSString *boundary = #"1010101010"; // DFH no need for the leading '--'
NSString *contentType = [NSString stringWithFormat:#"multipart/form-data; boundary=%#",boundary];
NSMutableDictionary *postVariables = [[NSMutableDictionary alloc] init];
[postVariables setValue:#"Abcd1234" forKey:#"key"];
NSString *requesturl = lblURL.text;
NSMutableString *myStr = [[NSMutableString alloc] init];
NSString *str;
// DFH - strategy is to have each line append its own terminating newline/return
str = [NSString stringWithFormat:#"--%#\r\n",boundary]; // DFH initial boundary
[myStr appendString:str];
NSArray *formKeys = [postVariables allKeys];
for (int i = 0; i < [formKeys count]; i++) {
str = [NSString stringWithFormat:#"Content-Disposition: form-data; name=\"%#\"\r\n%#\r\n",[formKeys objectAtIndex:i],[postVariables valueForKey:[formKeys objectAtIndex:i]]];
[myStr appendString:str];
str = [NSString stringWithFormat:#"--%#\r\n",boundary]; // DFH mid or terminating boundary
[myStr appendString:str];
}
NSLog(#"BODY: %#", myStr);
NSData *body = [myStr dataUsingEncoding:NSUTF8StringEncoding];
requesturl = [self encodeStringForURL:requesturl];
NSLog(#"requesturl=%#", requesturl);
NSURL *theURL = [NSURL URLWithString:requesturl];
self.activeDownload = [NSMutableData data];
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
[request setURL:theURL];
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
[request setTimeoutInterval:60.0];
[request setHTTPMethod:#"POST"];
[request setValue:contentType forHTTPHeaderField: #"Content-Type"]; // DFH you add addValue, I always use setValue
NSLog(#"URL : %#", requesturl);
NSLog(#"REQ : %#", request);
NSLog(#"ContentType \"%#\"", contentType);
if(body)
{
[request setHTTPBody:body];
}
NSLog(#"AllFields : %#", [request allHTTPHeaderFields]);
NSLog(#"HTTPBody : %#", [[NSString alloc] initWithData:[request HTTPBody] encoding:NSUTF8StringEncoding]);
NSLog(#"HTTPMethod : %#", [request HTTPMethod]);
conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
assert(conn);
}
I have used ASIHTTP Library and my problem is solved
Please glance at this and tell me why my NSURL *urlStringURL is alway an "invalid CRStringRef" Going blind trying to see what's wrong. Thanks!
EDIT: below code doesn't work since it's a GET. Can't encode the receipt to make a GET work. Good code follows bad code.
- (void) sendReceipt {
NSObject *rData = [[NSUserDefaults standardUserDefaults] objectForKey:#"purchaseReceipt"];
NSNumber *custData = [[NSUserDefaults standardUserDefaults] objectForKey:#"phoneNumber"];
NSString *urlString = [[NSString alloc] initWithString:#"https://www.privusmobile.info/Apple-???/?TYPE=GET"];
NSLog(#"Transaction to send %#,%#" , rData,custData);
urlString = [urlString stringByAppendingFormat:#"&Cust=IP%#", custData];
urlString = [urlString stringByAppendingFormat:#"&Receipt=%#", rData];
NSURL *urlStringURL =[NSURL URLWithString:[NSString stringWithFormat:#"%#",urlString]];
NSMutableURLRequest *urlRequest =[NSMutableURLRequest requestWithURL:urlStringURL];
NSString *params = [[NSString alloc]initWithString:urlString];
urlData = [[NSMutableData alloc]init];
[urlRequest setHTTPMethod:#"GET"];
[urlRequest setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES]];
NSURLConnection *connection = [NSURLConnection connectionWithRequest:urlRequest delegate:self];
connection = [[NSURLConnection alloc] initWithRequest:urlRequest delegate:self];
NSLog(#"started!");
}
END OF BAD CODE
The good code follows:
- (void) sendReceipt {
NSObject *rData = [[NSUserDefaults standardUserDefaults] objectForKey:#"purchaseReceipt"];
NSNumber *custData = [[NSUserDefaults standardUserDefaults] objectForKey:#"phoneNumber"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL:[NSURL URLWithString:#"https://www.privusmobile.info/Apple??????/default.aspx?"]];
[request setHTTPMethod:#"POST"];
[request setValue:#"text/xml" forHTTPHeaderField:#"Content-type"];
NSString *xmlString = [NSString stringWithFormat:#"<data><item>IP%# </item><item>%#</item></data>",custData,rData];
NSLog(#"XMLSTRING %#",xmlString);
[request setValue:[NSString stringWithFormat:#"%d",[xmlString length]] forHTTPHeaderField:#"Content-length"];
[request setHTTPBody:[xmlString dataUsingEncoding:NSUTF8StringEncoding]];
NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:request delegate:self];
NSLog(#"started! %#",connection);
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
NSString * strResponse = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"SERVER DATA %#", strResponse);
}
The clue was the encoding hints. Thanks.
Try encoding the url string. Most likely there are spaces in rData but I'm just guessing. Try this:
NSObject *rData = [[NSUserDefaults standardUserDefaults] objectForKey:#"purchaseReceipt"];
NSNumber *custData = [[NSUserDefaults standardUserDefaults] objectForKey:#"phoneNumber"];
NSString *urlString = [[NSString alloc] initWithString:#"https://www.privusmobile.info/Apple-App/?TYPE=GET"];
urlString = [urlString stringByAppendingFormat:#"&Cust=IP%#", custData];
urlString = [urlString stringByAppendingFormat:#"&Receipt=%#", rData];
NSString* escapedUrlString =[urlString stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding];
NSURL *urlStringURL =[NSURL URLWithString:escapedUrlString];