DidReceiveAuthenticationChallenge for NSURLConnection's SynchronousRequest - ios

I am using NSURLConnection's sendSynchronousRequest to communicate with server. I wanted to handle authentication which can be achieved using connection delegates but delegates are not called for a synchronous request.
NSData *data = [NSURLConnection sendSynchronousRequest:UrlRequest returningResponse:&response error:&error];
dispatch_async(dispatch_get_main_queue(), ^{
if(!error)
{
// Do something
}
else
{
// Handle error
}
});
However i thought of sending all the request asynchronously using
[NSURLConnection connectionWithRequest:menuRequest delegate:self];
But i have multiple connection in the same class and each connection's success and error are used to perform different task.If i use async request error and success are heard by delegates which are same for all the request in that class, i cannot find out which request failed and which request succeeded. I have two question
If there is a way to implement https for synchronous request.
How to find which connection failed or succeeded among multiple connections in the same class for asynchronous request.

You can achieve this in different ways.
You can put creds in url like https://username:password#domain.tld/api/user.json
You can add add you creds to NSURLCredentialStorage before synchronous connection call.
You can use code below to achieve.
- (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse *__strong*)response error:(NSError *__strong*)error
{
_finishedLoading=NO;
_receivedData=[NSMutableData new];
_error=error;
_response=response;
NSURLConnection*con=[NSURLConnection initWithRequest:request
delegate:self
startImmediately:NO];
[con start];
return _receivedData;
}
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
//handle the challenge
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
*_response=response;
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[_receivedData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
*_error=error;
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
}

Related

How can I pass data from the model to the view controller after loading a connection?

I'm working on login functionality for an app at the moment and I receive a dictionary from the server after connecting. I receive the dictionary in the function
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
which I have in my model. With the dictionary info received from this, I then want to send that dictionary to the view controller, but the function has already returned by the time connectionDidFinishLoading completes.
How can I pass the data back to the view controller?
You need to set teh delegate and implement the callback methods
NSURLRequest *urlRequest = [[NSURLRequest alloc] initWithURL:theURL];
NSURLConnection *urlConnection = [[NSURLConnection alloc] initWithRequest:urlRequest delegate:self startImmediately:NO];
[urlConnection start];
The delegate methods are
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[_detailsResponse setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[_detailsResponse appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(#"Error: %#, %#", [error localizedDescription], [error localizedFailureReason]);
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// Do what you want with the data here.
}

Get the http response code from every UIWebView request

I need to check the response status code while loading any of the url in the webview fo. For now we can consider any of the web application I am loading inside the web view.So I need to track down every request withing that webview and check out the response code accordingly. For finding the response code, I need to use NSUrlConnection inside the uiwebview's delegate method "shouldStartLoadWithrequest". Some thing like this -
- (BOOL) webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType{
NSURLConnection *conn = [NSURLConnection connectionWithRequest:request delegate:self];
if (conn == nil) {
NSLog(#"cannot create connection");
}
return YES;
}
And NSURLConnectionDelegate as --
- (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
NSLog(#"connection:didReceiveResponse");
[self log:#"received response."];
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
int status = [httpResponse statusCode];
NSLog(#"http status code: %d", status);
if (status == 200) {
NSLog(#"Response OK");
}
else {
NSLog(#"Response is not OK");
}
}
- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
NSLog(#"connection:didReceiveData");
}
- (void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
NSLog(#"connection:didFailWithError - %#", error);
}
- (void) connectionDidFinishLoading:(NSURLConnection *)connection{
NSLog(#"connectionDidFinishLoading");
}
But in this process, there are 2 calls on the server. One for the UIWebview and other for the NSUrlConnection. I just need a single call to the server in which I would be able to find the status code. Can anybody please guide me in this ?
I have implemented it using
NSURLProtocol
. For more details, you can check it here - NSURLProtocol

Call WSDL using REST Api in objective-c

I have WSDL url with me. I have two methods in the WSDL, I need to access those method and get response using REST api.
What I have tried is below?
I used the below code snippets for request and response. But I didnt get any response.
- (void)viewDidLoad
{
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURLNSURL : [URLWithString"https://mywebsite.com/service.svc?wsdl"]];
[request setHTTPMethod"IBillingSubmissionService_RegisterDevice_InputMessage"];
NSURLConnection *myConnection = [NSURLConnection connectionWithRequest:request delegate:self];
[myConnection start];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[dataWebService setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
NSLog(#"Response: %#",data);
[dataWebService appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSString *responseString = [[NSString alloc] initWithData:dataWebService encoding:NSUTF8StringEncoding];
NSLog(#"Response: %#",responseString);
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
NSLog(#"Eror during connection: %#", [error description]);
}
What ever I am doing above is correct? Can some one provide a sample code snippet to call and get response using REST?
I want to know the below:
1) How to pass the value to WSDL method?
2) How to pass a reqiest and get response?
You can not directly use the wsdl webservices in objective c but you have to first construct the reference base classes.
You can use wsdl2objc code generator to construct the base classes to call the wsdl webservice
and Please refer the usage instructions for how to use it.
UPDATE: As a my advice you can see my answer here

Reading Data after Webpage is completely done loading

I am making a login method on iOS that sends a GET request to a PHP page via url, when I try to read the output from the website, the data is read before the PHP can complete the mysql query, I was wondering if there were any way to wait until the webpage is completely done loading to read the data from it
code:
-(NSString *)getWebpageData:(NSString *)url {
NSURL *URL = [NSURL URLWithString:url];
NSError *error = nil;
NSString *content = [NSString stringWithContentsOfURL:URL encoding:NSUTF8StringEncoding error:&error];
return content;
}
I would try using NSURLConnection via sendAsynchronousRequest like so...
NSOperationQueue *myQueue = [[NSOperationQueue alloc]init];
[NSURLConnection sendAsynchronousRequest:request queue:myQueue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
//do something
}];
It's mostly self-explanatory that when the handler block is fired you have your content.
Another option would be to invoke the NSURLConnectionDataDelegate. When you call your URL it will fire a few methods to let you know when things are done.
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
//Fired on error
}
- (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite
{
//Fired First
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
//Fired Second
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
//Fired Third
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
//Fired Fourth
}
Using the delegate methods you're likely going to want to leverage didReceiveData so that you have your data right there. Good luck.

NSURLConnection - didReceiveData didn't get called - iOS & ARC

I'm currently experimenting with the twitter streaming api and i'm trying to get a stream with NSURLConnection. As it doesn't work with twitter, i simplified everything and tried to get some source-code out of google's website, but this doesn't work neither.
The connection starts and ends, but without calling the didReceiveData delegate. I'm sure i'm missing something. Hope you guy's can help me!
In the header: #interface ViewController : UIViewController <NSURLConnectionDataDelegate, NSURLConnectionDelegate, NSURLConnectionDownloadDelegate, NSURLAuthenticationChallengeSender>
And in the body:
- (void)viewDidLoad
{
[super viewDidLoad];
NSURLConnection *connection;
NSMutableURLRequest *request;
// Do any additional setup after loading the view, typically from a nib.
request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"http://www.google.com"]];
[request setHTTPMethod:#"GET"];
connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[connection start];
}
- (void)connectionDidFinishDownloading:(NSURLConnection *)connection destinationURL:(NSURL *)destinationURL {
NSLog(#"Stream finished.");
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
NSString *dataString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"%#", dataString);
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
NSLog(#"Connection failed!");
}
A couple of thoughts.
Your declaration of connectionDidFinishLoading doesn't look right. The standard NSURLConnectionDataDelegate method does not have a destinationURL parameter:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(#"%s", __FUNCTION__);
}
Given the presence of NSURLAuthenticationChallengeSender, if you're expecting a challenge (which you won't get with Google web site) then you'd obviously handle it accordingly:
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
// For example, if you have a userid/password to use, see if this is the first
// challenge, and then tell NSURLConnection to try using those credentials, and if
// it failed a second time, you might just cancel the authentication challenge.
if (challenge.previousFailureCount == 0) {
NSURLCredential *credential = [NSURLCredential credentialWithUser:kUserID password:kPassword persistence:NSURLCredentialPersistenceForSession];
[challenge.sender useCredential:credential forAuthenticationChallenge:challenge];
} else {
[challenge.sender cancelAuthenticationChallenge:challenge];
}
}
By the way, you do not want to call start method when you use initWithRequest or connectionWithRequest. It's only needed if you do a simple initWithRequest:delegate:startImmediately: and instruct it to not startImmediately.
Anyway, I used the following and it works fine:
- (void)viewDidLoad
{
[super viewDidLoad];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"http://www.google.com"]];
[NSURLConnection connectionWithRequest:request delegate:self];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(#"%s", __FUNCTION__);
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
NSString *dataString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"%s: %#", __FUNCTION__, dataString);
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
NSLog(#"%s error=%#", __FUNCTION__, error);
}
Someone said here that it was their SOAP format
NSURLConnection delegate method: didReceiveData not called ...Why ?? (iPhone SDK)
This also may be what you are looking for
NSURLConnection didReceiveData not called
Your NSURLConnection local variable connection is going out of scope at the end of viewDidLoad. Add a property to your ViewController to hold the NSURLConnection variable in scope.

Resources