How to properly encode UTF-8 in iOS using NSMutableURLRequest? - ios

I am trying to send information to a login web service but certain characters are giving me trouble.
For example, if the password is something like h+4hfP, the web service rejects it because the plus sign ('+') is not properly encoded to %2B.
The web service uses UTF-8 encoding so I have been building an NSData object with this NSString method, - (NSData *)dataUsingEncoding:(NSStringEncoding)encoding; choosing NSUTF8StringEncoding as the encoding.
This doesn't seem to be enough though.
The problem could also be with how I'm building an NSMutableURLRequest:
NSData *postData = [#"h+4hfP" dataUsingEncoding:NSUTF8StringEncoding];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:url]];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:contentLength forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody:postData];
How can I ensure the encoding is done properly?

Use
[theRequest setValue:#"application/json; charset=UTF-8" forHTTPHeaderField:#"Content-Type"];

You could percent encode the string before representing it as NSData:
NSString *password = [#"h+4hfP" stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet alphanumericCharacterSet]];
NSData *postData = [password dataUsingEncoding:NSUTF8StringEncoding];
...

This can be a solution:
I was facing this problem. After some hours and search, I discovered this:
http://madebymany.com/blog/url-encoding-an-nsstring-on-ios
Solution:
1st: You must create a method or class with content:
-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding withString:(NSString *) str{
return (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(NULL,
(CFStringRef)str,
NULL,
(CFStringRef)#"!*'\"();:#&=+$,/?%#[]% ",
CFStringConvertNSStringEncodingToEncoding(encoding)));
}
2nd: Use:
NSString *stringToSend = [self urlEncodeUsingEncoding:NSUTF8StringEncoding withString:stringToBeVerifyed];
Then
NSData *postData = [stringToSend dataUsingEncoding:NSUTF8StringEncoding];
[...]

Related

NSMutableURLRequest remove "+" sign from request

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.

How to Send JSON String with Special Charaters in iOS?

I'm new to iOS and i'm using the following code to make API Calls.
-(NSData *)sendDataToServer:(NSString*)url :(NSString*)params
{
NSString *postDataString = [params stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(#"postDataString :%#",postDataString);
NSData *postData = [postDataString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d",[postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
NSString *urlReq = [NSString stringWithFormat:#"%#", url];
[request setURL:[NSURL URLWithString:urlReq]];
[request setTimeoutInterval:180];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]];
responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSLog(#"response in Server: %#",responseString);
return responseData;
}
I'm sending the following string as params to the above method. If I send the following data without special characters, I'm getting the success response.
If i Add any special charters as like (&) with json I'm always getting the invalid response, that is the server always returns null.
So Can anyone please provide any suggestion to get the right response when using json string with Special characters like '&' etc.,
submited_data={"safty_compliance_fields":[{"safty_compliance_id":"641","fieldName":"sc1","fieldType":"editText","fieldValue":"wedgies Ig"},{"safty_compliance_id":"642","fieldName":"sc2","fieldType":"editText","fieldValue":"het &"}],"status_id":"2","product_detail":[{"dynamic_fields_id":"639","fieldName":"p1","fieldType":"editText","fieldValue":"data1"},{"dynamic_fields_id":"640","fieldName":"p2","fieldType":"editText","fieldValue":"data2"}],"inspection_id":"3","second_level":[{"questions":[{"checkListValue":"NO","checkListCommentValue":"Jgkjgjkj","sub_category_id":"452","checkListName":"sl1"},{"checkListValue":"YES","checkListCommentValue":"jk","sub_category_id":"453","checkListName":"sl2"},{"checkListValue":"YES","checkListCommentValue":"gh","sub_category_id":"455","checkListName":"sl3"},{"checkListValue":"YES","checkListCommentValue":"nm","sub_category_id":"456","checkListName":"sl4"}],"title":"sl1","entity_second_level_entry_id":"130"},{"questions":[{"checkListValue":"YES","checkListCommentValue":"Bonn","sub_category_id":"454","checkListName":"s22"}],"title":"s211","entity_second_level_entry_id":"131"}],"comment":"Jgkjgjkj","status":"Ongoing"}
You didn't post the percent encoded string, but the original string.

IOS JSON sending an email from Mandrill

I have an IOS application that I would like to send an email via Mandrill. I have tried to implement this, but its not working and Ive confused myself.
When pressing the button to send an email from the IOS application I log this error message:
{"status":"error","code":-1,"name":"ValidationError","message":"You must specify a key value"}
My code is:
NSString *post = [NSString stringWithFormat:#"{\"key\": \"abcdefg123456\", \"raw_message\": \"From: me#mydomain.com\nTo: me#myotherdomain.com\nSubject: Some Subject\n\nSome content.}"];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:#"https://mandrillapp.com/api/1.0/messages/send-raw.json"]];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
NSLog(#"Post: %#", post);
NSURLResponse *response;
NSData *POSTReply = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
NSString *theReply = [[NSString alloc] initWithBytes:[POSTReply bytes] length:[POSTReply length] encoding: NSASCIIStringEncoding];
NSLog(#"Reply: %#", theReply);
Please let me know where I am going wrong.
It looks you forgot the \" after "content.".
Try to write your "post" variable as follow:
NSString *post = [NSString stringWithFormat:#"{\"key\": \"abcdefg123456\", \"raw_message\": \"From: me#mydomain.com\nTo: me#myotherdomain.com\nSubject: Some Subject\n\nSome content.\"}"];
I hope it helps.

How to post a password with a & symbol

I am trying to create an app that sends a password through POST to a php website, but I am having trouble with the PostData. When the password contains a & symbol it thinks that the variable will be split into two.
For example:
Username: testuser
Email: email#email.com
Password: Pass&word1
The following would be the PostData
username=testuser&email=email#email.com&password=Pass&word1
^This breaks the password up
This is my code:
#try {
NSString *post = [[NSString alloc] initWithFormat:#"username=%#&email=%#&password=%#", usernameField.text, emailField.text, password1Field.text];
NSLog(#"PostData: %#",post);
NSURL *url=[NSURL URLWithString:#"http://mywebsite.com/test/register.php"];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%lu", (unsigned long)[postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
}
#catch (NSException *exception) {
NSLog(#"Exception: %#", exception);
}
EDIT
I also just realized that letters like: àìú are causing problems as well.
Ampersands have special meaning in HTTP requests. You'll need to URL encode those parameters to make sure that the server software knows that they are data.
You'll need to do something like this for each parameter in the request string:
NSString* encodedPassword = (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,
(CFStringRef)password1Field.text,
NULL,
(CFStringRef)#"!*'\"();:#&=+$,/?%#[]% ",
CFStringConvertNSStringEncodingToEncoding(NSUTF8Encoding));
Take a look at this reference for a great example of adding your URL encoder to the NSString class: http://madebymany.com/blog/url-encoding-an-nsstring-on-ios
As for your edit, characters like àìú are probably giving you problems because you are using NSASCIIStringEncoding. Try NSUTF8StringEncoding as it supports a much larger range of potential characters than ASCII.
Simple solution: Use '|' instead of '&' in your Objective C code.

API POST method not saving data in sql server

Hi I'm new to iphone development, I'm currently working with a project where I have a screen, in which user should enter their details, like username and password. I googled and find out about NSURLConnection for GET/POST/DELETE. I can GET data by the below codes,
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:#"http://************/api/Users"]];
[request setHTTPMethod:#"GET"];
[request setValue:#"application/json;charset=UTF-8" forHTTPHeaderField:#"Content-
Type"];
NSURLResponse *response;
NSData *GETData = [NSURLConnection sendSynchronousRequest:request
returningResponse:&response error:nil];
NSString *ResultData = [[NSString alloc] initWithBytes:[GETData bytes] length:[GETData
length] encoding: NSASCIIStringEncoding];
NSLog(#"ResultData: %#", ResultData);
But for POST method, i doesn't get any ideas of , how it functions and how it store record to sql server database, can't understand whether it s storing data or not, i tried the following codes,
username = #"Aravind.k";
password = #"1234/";
email = #"sivaarwin#gmail.com";
NSString *post = [NSString stringWithFormat:#"FirstName=%#&LastName=%#&WorkEmailAddress=%#",
username, password, email];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding
allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:#"http://*********/api/Users"]];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded;charset=UTF-8"
forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
NSLog(#"request: %#", request);
NSLog(#"postData: %#", postData);
NSURLResponse *response;
NSData *POSTReply = [NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:nil];
NSLog(#"POSTReply: %#", POSTReply);
NSString *theReply = [[NSString alloc] initWithBytes:[POSTReply bytes]
length:[POSTReply length]
encoding:NSASCIIStringEncoding];
NSLog(#"Reply: %#", theReply);
Same api url for both GET and POST, any suggestions regarding POST and DELETE will be grateful, Thanks in advance.And how we can get notified as the entered data is stored into the server.
First off: not checking for errors automatically leads to down votes ;)
Please edit your code with full error checks!
When using a MIME type application/x-www-form-urlencoded you need to properly encode the parameters.
I would suggest, to create a NSDictionary holding your parameters, e.g.:
NSDictionary* params = #{#"FirstName": firstName, #"LastName": lastName, #"password": password};
and then use the approach described in the following link to get an encoded parameter string suitable for using as a body data for a application/x-www-form-urlencoded message:
How to send multiple parameterts to PHP server in HTTP post
The link above implements a Category and a method dataFormURLEncoded for a NSDictionary which returns an encoded string in a NSData object:
NSData* postData = [params dataFormURLEncoded];
Note: The MIME type application/x-www-form-urlencoded does not have a charset parameter. It will be ignored by the server. You should set the header like below:
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
Otherwise, your code should work. I would strongly recommend to use the asynchronous version of the convenient method:
+ (void)sendAsynchronousRequest:(NSURLRequest *)request
queue:(NSOperationQueue *)queue
completionHandler:(void (^)(NSURLResponse*, NSData*, NSError*))handler

Resources