How to encode sharp sign in NSURL - objective-c

I have this scenario that I need to send a GET http request to the remote server. I went with NSURLConnection and intercept the request in HTTPScoop.
The url format is something like this:
http://domain.com?key=username##somehash&url=someotherurl.com
I am doing it like this:
NSString *urlString = [[NSString alloc]init];
urlString = #"http://domain.com?key=username##somehash&url=someotherurl.com";
NSString *encodedString = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString: [NSString stringWithFormat:encodedString]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL: url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
[request setHTTPMethod:#"GET"];
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:request delegate:self];
In this case I didn't escape the # sign, and the request I see in httpscoop is:
http://domain.com?key=username223somehash&url=someotherurl.com
If I escape the sharp sign to %23, it gets to something like this in httpscoop:
http://domain.com?key=username22523somehash&url=someotherurl.com
I have tried different combinations but always have issue with the sharp sign. Are there any walk-around for this? Thanks!

replace # with %23 (source).
edit - oops, didn't see the rest of your message. Not sure about NSURL, but I have had difficulty encoding parameters in URLs with NSURL before, too. I ended up using ASIHTTPRequest, which took care of all the encoding issues. I would recommend doing the same.

Related

NSURLConnection Unable to http post large file

We are trying to add in functionality into our app to allow it to POST a large file approx 50kb to our web service the file itself is a HTML template, however with the code below what we are finding is that the data seems to get cut off when the web service saves it.
The web service is currently designed to check the $_POST['html'] variable and write it to a file.
Is there a better way to do this and does anyone have any idea why the upload is not complete?
Thanks Aaron
NSString *myText;
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"template" ofType:#"htm"];
if (filePath) {
myText = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
}
NSURL *URL = [NSURL URLWithString:#"http://mywebsiteurl.com/receiveData.php"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
request.HTTPMethod = #"POST";
NSString *params = [NSString stringWithFormat:#"html=%#", myText];
NSData *data = [params dataUsingEncoding:NSASCIIStringEncoding];
[request addValue:#"8bit" forHTTPHeaderField:#"Content-Transfer-Encoding"];
[request addValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request addValue:[NSString stringWithFormat:#"%i", [data length]] forHTTPHeaderField:#"Content-Length"];
[NSURLConnection connectionWithRequest:[request autorelease] delegate:self];
I think it is because your Server set the post limit.Check the settings at your server side about the post data limit.
When I rechecked this question, I think maybe I found what was the problem. When I do HTTP post, I usually don't set the content-length by myself. I just encode my post data as key=value&.. form and use the [NSMutableURLRequest setHTTPBody:data] method to add the data to the NSMutableURLRequest. I think it will do the rest for you include set the content-length for you. Even though I am not very familiar with HTTP protocol, but I think maybe the content-length represent the whole post data length, but here you set the content-length value with the length of key value data length.

Windows Azure Authentication for Bing Search in Objective-C

On 01.08.12 Bing modified their search api to a Azure, How can I authenticate in Objective-C to use the new bing search api from Azure?
My best guess is to learn from the provided PHP example in the migration word document!! http://go.microsoft.com/fwlink/?LinkID=248077 (Oh god, can't you setup a web page!) or this Java Question - Bing Search API Azure Marketplace Authentication in Java
I'm using ASIHTTPRequest to authenticate with following code.
NSString *queryString = [NSString stringWithFormat:#"'%#'", queryString];
queryString = [queryString urlEncodeUsingEncoding:NSUTF8StringEncoding]; //You'll have to implement url encoding method, preferably in a string category file
NSString *urlString = [NSString stringWithFormat:#"https://api.datamarket.azure.com/Data.ashx/Bing/Search/v1/Image?Query=%#&Market='en-US'&$top=50&$format=json", queryString];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:urlString] ];
[request setAuthenticationScheme:(NSString *)kCFHTTPAuthenticationSchemeBasic];
[request setUsername:#"YOUR_KEY_HERE"];
[request setPassword:#"YOUR_KEY_HERE"];
[request setDelegate:self];
[request startAsynchronous];
Please note, no appID required. just instead pass your key as username and password. It is successfully getting the data.
However, can't really convert the data to NSString. tried every encoding but can't get the string from the data. Initial googling says it's UTF-8 encoded. But no success.
For above code to work, you must add ASIHTTP framework.
Another thing is, my guess is passing base64 encoded string with this format your_key:yourkey should also work with basic authentication.
I was able to get it to work using just NSUrlConnection. You must first base64encode
NSString *keyString = [NSString stringWithFormat:#"%#:%#", BING_SEARCH_API_KEY, BING_SEARCH_API_KEY];
NSData *plainTextData = [keyString dataUsingEncoding:NSUTF8StringEncoding];
NSString *base64String = [plainTextData base64EncodedString];
Setup your request
NSMutableURLRequest *req = [[NSMutableURLRequest alloc] init];
[req setURL:[NSURL URLWithString:searchUrl]];
NSString *authValue = [NSString stringWithFormat:#"Basic %#", base64String];
[req setValue:authValue forHTTPHeaderField:#"Authorization"];
Make the request
NSError *error = [[NSError alloc] init];
NSHTTPURLResponse *response = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:req returningResponse:&response error:&error];
Look at the documentation about how to form searchUrl, and then process data according to the format you specified in $format= (I used json, so mine looks like):
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
I left out error handling, dont forget to add that by checking response as well as error.

POST request in Objective-C

Searching the web for some method to send POST requests in Objective-C, I came up with some solutions.
That's what I've got:
responseData = [NSMutableData new];
NSURL *url = [NSURL URLWithString:#"http://mydomain.com/page.php?"];
NSString *myParameters = [[NSString alloc] initWithFormat:#"str=hello"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:[myParameters dataUsingEncoding:NSUTF8StringEncoding]];
The response I receive is an error, because the POST variable "str" hasn't been set.
What am I doing wrong?
You will have to:
set the content type header of the request ("application/x-www-form-urlencoded"). You can set the header by using the setValue:forHTTPHeaderField: method of an NSMutableURLRequest instance.
make sure, that the body actually is actually "Form URL encoded". The example you give looks good, but if you add other parameters, or parameter values containing special characters, make sure, that these are properly encoded. See CFURLCreateStringByAddingPercentEscapes.
It looks like your parameters are intended to be URL parameters (typically in name1=value1&name2=value2 form). You usually don't want to put them in the HTTP body like you are currently doing. Instead, append them to your URL:
NSString *requestStr = #"hello";
NSString urlString = [NSString stringWithFormat:#"http://mydomain.com/page.php?str=%#", requestStr];
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest doesn't provide a more generic way to do this, although you can look at this SO question and its answers for ideas on how many people deal with this kind of requirement. There are also free and/or open source libraries out there that aim to make this kind of request easier to code.

Unable to create Request: Bad URL

When i try to look for a location like this: Florida,USA it goes OK, but when i try it like this: Florida USA, i got that error:
Unable to create Request (bad url?)
The problem belongs with the spaces on the location taped, is there any way to resolve that?
NSString *urlString = [NSString stringWithFormat:#"https://maps.googleapis.com/maps/api/geocode/json?address=%#&sensor=true",theLocationString];
//Create a URL object.
NSURL *url = [NSURL URLWithString:urlString];
ASIFormDataRequest *request=[ASIFormDataRequest requestWithURL:url];
I think the problem is that you need to urlencode your string. A space character isn't a valid url string:
NSString *urlString = [NSString stringWithFormat:#"https://maps.googleapis.com/maps/api/geocode/json?address=%#&sensor=true",theLocationString];
//Create a URL object.
NSURL *url = [NSURL URLWithString:[urlString stringByAddingPercentEscapesUsingEncoding:
NSASCIIStringEncoding]];
ASIFormDataRequest *request=[ASIFormDataRequest requestWithURL:url];
If NSASCIIStringEncoding doesn't work you could try: NSUTF8StringEncoding
..fredrik

extract data from cocoa http get request

I implemented the following code:
NSURL *url = [ NSURL URLWithString:[ NSString stringWithFormat: #"http://www.google.com/search?q=%#", query ] ];
NSURLRequest *request = [ NSURLRequest requestWithURL: url ];
I want to extract the body from what I receive back from the url above. I attempted:
NSData *data = [request HTTPBody];
The data variable doesn't return any data? Am I going about extracting the data out of the request the right way?
Thanks!
If you're just trying to get a web page, you can use this.
NSURL *url = [ NSURL URLWithString: [ NSString stringWithFormat: #"http://www.google.com"] ];
NSString *test = [NSString stringWithContentsOfURL:url];
If you really want to convert the data from NSData you can use this:
NSString *myString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSURLRequest just defines a request — it doesn't do anything by itself. To actually make a request, you need to give the request to an NSURLConnection.
Also, as indicated in the documentation, the HTTPBody is data that's sent with the request, not the response body.
There is an article on www.eigo.co.uk which shows exactly how to do the request and get the response in a string variable but the chunk of code you need is...
NSString * strResult = [[NSString alloc] initWithData:oResponseData encoding:NSUTF8StringEncoding];
Check out the article here http://www.eigo.co.uk/iPhone-Submitting-HTTP-Requests.aspx