Windows Azure Authentication for Bing Search in Objective-C - 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.

Related

Objective C Update RESTful Webservice

I have a web service that allows me to update records on in our database.
The columns in the table are as follows:
allowsActions
assetID
inventoryObjectID
objectDescription
quantity
retired
serialNumber
action
I'm using the following to GET data from the webservice.
NSString *urlString = [NSString stringWithFormat:#"%#", inventoryAndActionsWebservice];
NSURL *url = [NSURL URLWithString:urlString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"GET"];
Then shoving into a dictionary like so:
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError)
{
if (data.length > 0 && connectionError == nil)
{
NSLog(#"WE HAS THE DATAS");
NSDictionary *inventory = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
// Then storing the values in CoreData here
}
}
What would be the syntax for updating the webservice? It expects an object in the body of the service call (POST).
NSMutableURLRequest let's you setHTTPBody: and setHTTPMethod:.#"POST"is the way to do a post. Most services need to know the body length and encoding set in headers. (seeaddValue:forHTTPHeaderField:`) for that.
The only reason this topic is tricky is because the developer is forced to grapple with two problems at once: what constitutes a valid request for my server, and (2) how do I form that request with iOS? Part (2) is actually pretty easy once you get a valid request.
The best way to proceed is to get an example working using curl (or something equivalent). Then move on to producing that request in iOS. If you have trouble, ask a question here of the form: "I know my server needs X, here's my code to produce X, but I'm getting this error Y".
So the syntax that I was looking for was ultimately this:
NSString *jSONString = [NSString stringWithFormat:#"{\"MediaInventoryObjectsId\":%d,\"AssetId\":%d,\"Quantity\":%d,\"SerialNumber\":\"%#\",\"Description\":\"%#\",\"AllowActions\":%d,\"Retired\":%d}",inventoryObjectId, assetID, quantity, serialNumber, description, allowActions, retired];
// Convert jSON string to data
NSData *putData = [jSONString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
// Instantiate a url request
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
// Set the request url format
[request setURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#/%d", inventoryAndActionsWebservice, inventoryObjectId]]];
[request setHTTPMethod:#"PUT"];
[request setHTTPBody:putData];
[request setValue:#"application/json" forHTTPHeaderField:#"content-type"];
// Send data to the webservice
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];

google translate in Objective-C

I have seen some post which uses google translate web page.
NSString* englishString = [englishInputArray objectAtIndex:i];
NSString *urlPath = [NSString stringWithFormat:#"/translate_a/t?client=t&text=%#&langpair=en|fr",englishString];
NSURL *url = [[NSURL alloc] initWithScheme:#"http" host:#"translate.google.com" path:urlPath];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init] ;
[request setURL:url];
[request setHTTPMethod:#"GET"];
NSURLResponse *response;
NSError *error;
NSData *data;
data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSString *result = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
NSLog(#"Text: %#",result);
I have two questions:
1)the json return from the web page look like this
[[["Bonjour","Hello","",""]],[["interjection",["bonjour","salut","all\u00f4","tiens"]]],"en",,[["Bonjour",[5],1,0,1000,0,1,0]],[["Hello",4,,,""],["Hello",5,[["Bonjour",1000,1,0]],[[0,5]],"Hello"]],,,[],1]
Other than doing string manipulation is there a way to get the the exact translation string alone ie in tis case "Bonjour" alone.
2: Does anybody know if this is this a free service ? Google apis seems to be a paid service. But if you use web page is that a free service.
No. All API's I've used have always been either JSON or XML. There is no reason to use string manipulation when you can just parse the data into a readable structure
If you are looking to use another service that isn't paid, keep in mind there are normally strict limitations. Try something like: SDL https://www.beglobal.com/developers/api-documentation/
Have you read Google's Translate API Documentation?
https://developers.google.com/translate/
For example performing a GET request like so
GET https://www.googleapis.com/language/translate/v2?key=INSERT-YOUR-KEY&source=en&target=de&q=Hello%20world
Should return the following response:
{
"data": {
"translations": [
{
"translatedText": "Hallo Welt"
}
]
}
}
With this you can just parse the JSON and display the data

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.

How do i sign into a website using username/password from XCode?

I'm pretty much new into Objective-c programing , and my knowledge of PHP is almost nothing.
Anyway, I'm trying to do a login screen in my App which has 2 text fields for username and password, and a button which suppose to enter the username/password into a website sign in page , and connect to the account.
I'm not sure if I'm on the right way but here is a sample of the code i made:
-(IBAction)ButtonClicked:(id)sender
{
NSString *content = #"username=blabla&password=123456";
NSData *data=[content dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postlenght=[NSString stringWithFormat:#"%d",[data length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"http://roadster.co.il/forums/ucp.php?mode=login"]];
[request setHTTPMethod:#"POST"];
[request setValue:postlenght forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody:data];
NSError *error=nil;
NSURLResponse *response=nil;
NSData *result=[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
[webview loadRequest:request];
}
As you can see the website I'm trying to log into is
http://roadster.co.il/forums/ucp.php?mode=login
I'm sorry but the website is in Hebrew but it not the matter. can you please tell me why i don't manage to sign in using this code? (tried with the real password/username)
You are attempting to make the request twice.
NSError *error=nil;
NSURLResponse *response=nil;
NSData *result=[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
[webview loadRequest:request];
Both +sendSynchronousRequest:returningResponse:error: and -loadRequest: send the request to the server. You only want to do one or the other. Either, remove the first three lines of code, or use -loadHTMLString:baseURL: to load the result into web view.
NSString *HTMLString = [[[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding] autorelease];
[webview loadHTMLString:HTMLString baseURL:[NSURL URLWithString:#"http://roadster.co.il/forums/ucp.php?mode=login"]];
Make sure "http://roadster.co.il/forums/ucp.php?mode=login" is the URL the form POSTs to, not the URL of the form (you can find this in the "action" attribute of the HTML's form tag.

Getting a section of an NSString

In my app i'm creating now i use goo.gl's url shortener api to shorted urls. I have it nearly working, I can send the longUrl to retrieve the short one in a NSString but it's in this format:
{
"kind": "urlshortener#url",
"id": "http://goo.gl/something",
"longUrl": "http://somethinglonggggg/"
}
I just wondered if there is a way to just take the id (short url) from that.
Here's what I have so far:
NSString *longURL = urlText.text;
NSData *reqData = [[NSString stringWithFormat:#"{\"longUrl\":\"%#\"}", longURL] dataUsingEncoding:NSUTF8StringEncoding];
NSMutableURLRequest *request = [NSMutableURLRequest
requestWithURL:[NSURL URLWithString:#"https://www.googleapis.com/urlshortener/v1/url"]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:20];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:reqData];
NSError *err = [[NSError alloc] init];
NSData *retData = [NSURLConnection sendSynchronousRequest:request
returningResponse:nil
error:&err];
if([err domain]) return;
NSString *retString = [[NSString alloc] initWithData:retData encoding:NSUTF8StringEncoding];
if([retString rangeOfString:#"\"error\""].length) return;
NSLog(#" longUrl equals %# ", longURL);
NSLog(#" retString equals %# ", retString);
urlText.text = retString;
You defenitively need to turn that into an NSDictionary (that JSON syntax is for a dictionary, or an object, however you want to call it.
The google API for Objective-C supports JSON parsing to turn the response into objects.
You can find it here.
If all you need is parsing the JSON, I would recommend either JSONkit or TouchJSON.
They both work in very similar ways, you give them the string and they will give you back objects.
The info for the individual usage of the libraries can be found on the readme of the respective project, there you will find how easy to use they are.
You would then acces the different values using:
NSString *short URL = [object valueForKey:#"id"];
This is the best way to interact with REST services.
Hope it helps!