Bing Search API -The authorization type you provided is not supported(ios) - bing-api

I am making use of Bing Search API available on Windows Azure Marketplace.
Subscription Type: Bing Search API (5000 transactions per month free).
I have obtained the account key.
Still I get response as
**The authorization type you provided is not supported.Only Basic and OAuth are supported**
When I copy url in the browser it asks for the user name and password (only password is mandatory and it is nothing but the account key) and after validating I can see data in XML/JSON format.
How I can achieve this through my program?
My code is:
NSString *urlString = [NSString stringWithFormat:#"%s","https://api.datamarket.azure.com/Data.ashx/Bing/Search/v1/Web?$format=json&$top=8&Query='querystring'"];
NSURL *url = [NSURL URLWithString:urlString];
NSData *data = [NSData dataWithContentsOfURL:url];
NSLog(#"%#",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]) ;
NSURLRequest *request = [NSURLRequest requestWithURL:url] ;
NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];
[connection start] ;

Related

How to localize Parse push notifications?

It looks like Apple already has built-in functionality to localize PUSH notifications by including loc-key in the aps payload. However, I don't believe Parse's iOS SDK allows you to set that key yourself using sendPushInBackground. Is there any way to localize PUSHs using Parse without first routing to my own server?
PFQuery *pushQuery = [PFInstallation query];
[pushQuery whereKey:#"user" equalTo:author];
NSString *key = #"PUSH_LOC_KEY_SEND_TO_AUTHOR";
NSArray *args = #[name]
NSDictionary *data = #{
#"alert": #{#"loc-key": key,
#"loc-args": args},
#"badge": #"Increment",
#"sound": #"default"
};
PFPush *push = [[PFPush alloc] init];
[push setQuery:pushQuery];
[push setData:data];
Then in Localizable.strings(Base) add:
"PUSH_LOC_KEY_SEND_TO_AUTHOR" = "%# sent you a message";
in Localizable.strings(French) add:
"PUSH_LOC_KEY_SEND_TO_AUTHOR" = "%# vous envoyé un message";
And note, that after you user authorises app, you should add current user object to installation so we can PFQuery him (as shown above):
PFInstallation *installation = [PFInstallation currentInstallation];
installation[#"user"] = [PFUser currentUser];
[installation saveEventually];
The alert key in the data dictionary used with PFPush can be set to a dictionary instead of a string.
For anyone who finds this in the future, mine looked like this:
NSDictionary *data = [NSDictionary dictionaryWithObjectsAndKeys:
#{#"loc-key":#"NEW_MESSAGE_PUSH", #"loc-args":#[sender.name]}, #"alert",
#"default", #"sound",
#"Increment", #"badge",
sender.pid, #"senderID",
nil];

dictionaryWithContentsOfFile and Sandbox

I've created a mac app that load a xml file from an user selected folder, and after using the app, the user saves a customized file (.adgf)
When i try to load the .adgf file (that is a plist file) that has the xml path within one record i call
dictionaryWithContentsOfFile but it return me a "nil". I think the problem is the sandbox (sometime it works sometime not). The string path is correct.
Maybe when the user load the xml file should i save within of particular app "Document folder"?
Edit:
I'm trying right now the Bookmark Data solution and I retraive a NSURL but it doen't work. The code I'm using is this:
- (NSData *)bookmarkFromURL:(NSURL *)url {
NSError *error = nil;
NSData *bookmark = [url bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope
includingResourceValuesForKeys:NULL
relativeToURL:NULL
error:&error];
if (error) {
NSLog(#"Error creating bookmark for URL (%#): %#", url, error);
[NSApp presentError:error];
}
return bookmark;
}
- (NSURL *)urlFromBookmark:(NSData *)bookmark {
NSURL *url = [NSURL URLByResolvingBookmarkData:bookmark
options:NSURLBookmarkResolutionWithSecurityScope
relativeToURL:NULL
bookmarkDataIsStale:NO
error:NULL];
return url;
}
After the user stores the file you should take the bookmark data from the URL using
-[NSURL bookmarkDataWithOptions: includingResourceValuesForKeys: relativeToURL: error:]
Use NSURLBookmarkCreationWithSecurityScope for the options.
This NSData object should be stored somewhere (plist?) and when you want to read the file again in a later session you can create a sandbox compliant NSURL from the bookmark data using +[NSURL
URLByResolvingBookmarkData:options:relativeToURL:bookmarkDataIsStale:error:]

NSURLRequest with UTF8 password

Here is a method I've written to connect to a server and get a user auth token:
+ (void)getAuthTokenForUsername:(NSString *)username
password:(NSString *)password
completionHandler:(void (^)(NSString *, NSError *))completionHandler
{
username = [username URLEncodedString];
password = [password URLEncodedString];
NSString *format = #"https://%#:%##api.example.com/v1/user/api_token?format=json";
NSString *string = [NSString stringWithFormat:format, username, password];
NSURL *URL = [NSURL URLWithString:string];
[NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:URL]
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *URLResponse, NSData *data, NSError *error)
{
NSString *token;
if (data) {
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
token = [NSString stringWithFormat:#"%#:%#", username, dictionary[#"result"]];
}
completionHandler(token, error);
}];
}
A URL then looks something like this: https://username:hello%C2%B0#api.example.com/v1/user/api_token?format\=json, where the password is hello°. The URLEncodedString method properly encodes everything as in the example, but the request never works. The problem is not with escaping or the server, because I can curl the same URL and I get nice JSON and authentication works, even though there is a non-ASCII character in the password. It also works from other programming languages like ruby or python. But the same url never works with NSURLConnection and it also doesn't work in Safari, which of course uses NSURLConnection. I get an 'The operation could not be completed' with a '401 Forbidden' every time.
(My code works fine when the password just contains ASCII characters. I also tried using the NSURLCredential methods, same problem.)
What do I need to do for NSURLConnection to work with such a URL as https://username:hello%C2%B0#api.example.com/v1/user/api_token?format\=json where the password contains non-ASCII characters?
I have just performed several tests against my mockup server and I think I have a solution for you.
First of all, when you add username & password to an URL, they are not actually send to the server as part of the URL. They are sent as part of the Authorization header (see Basic access authentication).
The fastest workaround for you is to do
NSURLRequest* request = [NSURLRequest requestWithURL:URL];
NSString* usernamePassword = [[NSString stringWithFormat:#"%#:%#", username, password] base64Encode];
[request setValue:[NSString stringWithFormat:#"Basic %#", usernamePassword] forHTTPHeaderField:#"Authorization"]
To understand the problem, let's go a bit deeper. Let's forget NSURLConnection sendAsynchronousRequest: and let us create an old-fashioned connection with a NSURLConnectionDelegate. Then in the delegate, let's define the following methods:
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
return YES;
}
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
NSLog(#"Proposal: %# - %#", challenge.proposedCredential.user, challenge.proposedCredential.password);
NSURLCredential* credential = [NSURLCredential credentialWithUser:#"username"
password:#"hello°"
persistence:NSURLCredentialPersistenceNone];
[challenge.sender useCredential:credential forAuthenticationChallenge:challenge];
}
If you don't create these methods, the username & password from your URL won't ever be added to the HTTP header.
If you add them, you'll see that the proposed password is hello%C2%B0. Obviously, that's wrong.
You can see the problem directly from
NSLog(#"Password: %#", [[NSURL URLWithString:#"http://username:hello%C2%B0#www.google.com"] password]);
which prints
hello%C2%B0
I believe this is a bug in the framework. NSURL returns password encoded and NSURLCredential doesn't decode it so we are left with an invalid password.

Ignoring SSL certificate errors with NSURLConnection

I'm using [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)] to pull data from a web service, but the web server has a self-issued certificate, causing this error to appear:
Error displayed using:
NSAlert *a = [NSAlert alertWithError:error];
[a runModal];
Is there any way to ignore this error and continue anyway?
Following the instructions in the linked question, I defined a dummy interface for NSURLConnection:
#interface NSURLRequest (DummyInterface)
+ (void)setAllowsAnyHTTPSCertificate:(BOOL)allow forHost:(NSString*)host;
#end
And called the method before creating the request:
[NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:[url host]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
This suppressed the error about the certificate being invalid.
This may be rejected by Apple. Use the proper implementation of NSConnectiondatadelegate:
see a way around it:
Stackoverflow response to similar question

NSURL from NSURLConnection?

It seems dead simple, as to create an NSURLConnection I usually do this:
NSURL *theURL = [NSURL URLWithString:urlString];
NSURLRequest *req = [NSURLRequest requestWithURL:theURL];
NSURLConnection *connection = [NSURLConnection connectionWithRequest:req delegate:self];
But how can I get the URL back in the delegate methods? Short of hanging on to them myself (I'm running many connections at once, so this becomes slightly messy). It seems as though I should be able to get the URL back from a connection.
Am I missing something?
In -connection:didReceiveResponse: you can get the URL. Note that this may not be the same URL you created the connection with since the connection may have been redirected.
- (void)connection:(NSURLConnection *)connection
didReceiveResponse:(NSURLResponse *)response {
NSURL * url = [response URL]; // The URL
}

Resources