How to retrieve a response from server for the request sent? - iphone

I am developing an application that connects to a remote web server and exchanges data with the web server frequently. First screen of my application provides login screen that authenticates user.
I am able to authenticate user on the web server by sending a request to the server but unable to get response from the server to display success alert to the user on the iphone. In clear, I am not getting any response.
The server I'm using is developed in Java.
I am using the following to send the request to server.
NSString *post = #"username=";
post = [post stringByAppendingString:username];
post = [post stringByAppendingString:#"&password="];
post = [post stringByAppendingString:password];
NSData *postData = [post dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
[request setURL:[NSURL URLWithString:#"http://example.com/login.action?"]];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody:postData];
NSURLConnection *conn=[[NSURLConnection alloc] initWithRequest:request delegate:self];
And,
- (void)connectionNSURLConnection *)connection didReceiveDataNSData *)data
{
[receivedData appendData:data];
NSString *ReturnStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"In \"didReceiveData()\" : receivedData = %#",receivedData);
NSLog(#"Return String : %#", ReturnStr);
}
This function is never called.
What should I do to receive response for the request I have sent?
A brief collection of my queries:
Example: Login screen that validates a user in Java server
I am sending request that I am able to see at the console of my server application.
I'm unable to get response for the request.
In which format the response data must be sent?
Would someone provide a clear picture of data exchange between the iPhone application and a Java servlet?
Update
I have implemented these three methods also. But no response from server. Can you guide me the process of developing LOGIN application that communicates with a JAVA server by requests and responses? I am stuck with communicating.
Yeah, my server is receiving request from iphone. I am able to see the request that is sent to the server.
I am not able to understand how the data exchange between iphone application and JAVA server takes place. I'm a newbie to this iphone development.

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[responseData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[responseData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
NSString *failureMessage = [NSString stringWithFormat:#"Connection failed: %#", [error description]];
NSLog(failureMessage);
}
Try implementing these three methods as well, you might be getting an error or no response. You can tell by using these methods.

you should verify that the server is actually recieving the request from the iphone.
a simple php script should return something.
<?php
echo print_r($_GET, true);
echo print_r($_POST, true);
?>
create a dummy app that makes a request to the script and displays the response

I'm not sure what authentication you refer to with LOGIN, but if the server requires HTTP Auth, you need to implement the delegate method
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge;

I am using the following to send the request to server.
The code looks OK, but where is this code and what happens before and after the code you've shown us? Is it in a handler for a button press? Is it in a background thread?
For the asynchronous load you are using to work properly, you need to be on a thread with a default run loop, e.g. the main thread. And this code must return control to the run loop, i.e. must not busy wait doing something else.
Another thing to check is your server - is it in fact sending a response? If you send the same request from a browser, what content length do you get back?
Edit: it may help if you also show the java action handler on the server side. For example, does it send a HTTP redirect if the login is successful? And are you implementing the following delegate method:
- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse
...and if so, what does that method look like. I'm wondering if you've maybe implemented this method and not got the right logic in there, thus stopped a redirect from happening.

U can do it this way...
-(NSString* )createWebServiveRequest:(NSString *)urlLink{
NSURL *url = [NSURL URLWithString:urlLink];
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:60];
NSData *returnData = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse: nil error: nil ];
NSString *responseString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
return responseString;
}
call the above method with the NSString containing url.....and capture it in the method call.

Related

Web service to fetch data return null in ios 6 but not in ios 7

I am consuming Web Service to fetch data and it returns a set of data from server, this works great before i install xcode 5, previously my app was compatible with ios6 now i changed to ios 7. Now i have one issue while fetching data from web service .
When i go first time to the UIViewController view i call web service in -(void)ViewDidLoad and no data return and if i call one more time ( without going back from view, i call again the same web service) it returns data, when i call first time it returns empty data but second time it return data, This is happening in ios 6 but the same code work perfect without any web service issue in ios 7. after i change
I am Receiving response from server but the data inside is null for first time, but the same time i run in ios 7 device its return data, so i don't understand where i am wrong??????
NSMutableData *serverData;
//delegate methods for NSURLConnection
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSString *str = [[NSString alloc] initWithData:serverData encoding:NSUTF8StringEncoding];//here i am initializing
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[serverData appendData:data]; // here i get data that is null but i get response from server
}
Myviewwillappear code here...
- (void)viewWillAppear:(BOOL)animated {
[self performSelector:#selector(GetDataFromServer) withObject:nil afterDelay:0.001];
}
- (void) GetDataFromServer {
NSString *soapMessage = [NSString stringWithFormat:#"<?xml version=\"1.0\" encoding=\"utf-8\"?>"
#"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"
#"<soap:Body>"
#"<GetProductList xmlns=\"http://tempuri.org/\">"
#"<inCompany>%#</inCompany>"
#"<inUserName>%#</inUserName>"
#"<inType>%#</inType>"
#"<inTypeValue>%#</inTypeValue>"
#"<inSearchVal>%#</inSearchVal>"
#"<inPage>%#</inPage>"
#"</GetProductList>"
#"</soap:Body>"
#"</soap:Envelope>",Company,Username,type,typevalue,searchval,page];
NSURL *url = [NSURL URLWithString:PVBASE_URL];
NSString *msgLength = [NSString stringWithFormat:#"%d",[soapMessage length]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request addValue:#"text/xml; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[request addValue:PVPRODUCTLIST forHTTPHeaderField:#"SOAPAction"];
[request setHTTPMethod:#"POST"];
[request addValue:msgLength forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody:[soapMessage dataUsingEncoding:NSUTF8StringEncoding]];
connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
if (connection) {
if (serverData) {
serverData = nil;
}
serverData = [[NSMutableData alloc] init];
}
connection = nil;
}
Basically i have en-counted this issue several times as when ever viewDidLoad execute didn't get any data but explicit call from IBaction it does. this is nothing to deal with iOS. basic problem with your web-service call.
You might be be calling data with using public variable which not execute or initialize.
Please provide your code for better understanding.
Thanks !!
I thought I would share my answer here as a possible solution. I had a similar problem occur with iOS6 and when I upgraded to iOS7 the network stack appeared to not be working because I was not getting data on the didRecieveResponse function of NSURLConnection. When in actuality from comparing how my code acted between iOS platforms it only looked like I was not receiving data from the didRecieveResponse function because sometimes the expectedContentLength mostly returned -1, but this also happened in iOS 6. In iOS7 the problem originated from another source that is unrelated to this example or my network connection that was affecting my use of NSOperation. So my point is, possibly the problem is not your platform differences but your code running your functionality. I would go through your code again for errors.

NSURLConnection distinguish 2 different request

In my app I need to download and post some data...
First of all I need to download some data and then I need to do a post request.
I Use async request to don't freeze the UI of my app...
But when I call my method to post some data... I don't care about data returned from server.
But the this method are called also when I do some post request.
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)aResponse
{
NSLog(#"------------------------------- connectionDidReceiveResponse");
expectedResponseLength = [NSNumber numberWithFloat:[aResponse expectedContentLength]];
URLresponse = aResponse;
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[self.responseData appendData:data];
}
How can I do my post request like this below without calling (automatic) this 2 methods (up) (used when I download info) and without freezing user GUI (I don't care data when I do post request but I need data in the 1st case)?
My post request is this:
- (void)postRequestWithURLState:(NSString *)url
{
NSString *bodyRequest = nil;
NSURL *requestURL = [NSURL URLWithString:url];
NSMutableURLRequest *theRequest = [[NSMutableURLRequest alloc] init];
//NSLog(#"-------------- bodyRequest: %#", bodyRequest);
[theRequest setURL:requestURL];
[theRequest setTimeoutInterval:2.0];
[theRequest setHTTPMethod:#"POST"];
[theRequest setHTTPBody:[bodyRequest dataUsingEncoding:NSASCIIStringEncoding]];
[self.oauthAuthentication authorizeRequest:theRequest];
NSURLConnection *conn = [NSURLConnection connectionWithRequest:theRequest delegate:self];
self.web = conn;
}
I was looking around the internet for a solution, I eventually just created my own subclass of NSURLConnection and assigned a tag variable to distinguish. Check out this blog post for more information
You can hold a reference to each of the different requests after performing them, then make some conditional code in the delegate methods that does something different for the two.
That's a rudimentary solution and feels like treating symptoms to me. Maybe you should refactor your approach and create controllers for each of the two operations and perform all of network communication there (it seems like you're doing it all in a view controller now) rather than where you're doing it now.

download and save zip file to iphone

i want to download the zip file from web but unable to figure out that how it is possible
i can download image /text/xml file but unable to download a zip file
Can someone guide me how to download zip files from web?
Thanks
If you're using NSURLConnection, it works exactly the same way no matter which type the file has.
Example: (typed off of my head, no guarantee that it works this way and you should obviously implement error checking)
- (void) download
{
self.loadedData = [NSMutableData data]; // make 'loadedData' a property of the class
NSURL *url = [NSURL URLWithString:#"http://..."];
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url
cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
timeoutInterval:20.0];
[urlRequest setValue:#"Optional User Agent" forHTTPHeaderField:#"User-Agent"];
// shoot it off
NSURLConnection *mainConnection = [NSURLConnection connectionWithRequest:urlRequest delegate:self];
if (nil == mainConnection) {
NSLog(#"Could not create the NSURLConnection object");
}
}
Then you must handle the incoming data in the delegate methods, e.g. to just save your data:
- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[loadedData appendData:data];
}
Take a look at the other delegate methods and implement them, you should deal with authentification challenges and fail responses. You can also for example set:
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
in connection:didReceiveResponse: and set it to NO again in connectionDidFinishLoading:.

Load HTML NSString into a UIWebView

Im doing a project where I connect to a webpage using the NSURLConnection to be able to monitor the status codes that are returned (200 OK / 404 ERROR). I would like to send the user to the top url www.domain.com if I recieve 404 as status code and if i recieve as 200 status code I would like to load the page in to a webview. I have seen several implementations of this problem by creating a new request but I feel that it is unnecessary since you already received the html in the first request so i would just like to load that HTML in to the webView.
So i try to use the [webView loadHTMLFromString: baseURL:] but it doesn't always work, I have noticed that when i print the NSString with html in the connectionDidFinnishLoading it sometimes is null and when I monitor these cases by printing the html in didReceiveData a random number of the last packets is NULL (differs between 2-10). It is always the same webpages that doesn't get loaded. If I load them to my webView using [webView loadRequest:myRequest] it always works. My implementation looks like this perhaps someone of you can see what Im doing wrong.
I create my first request with a button click.
-(IBAction)buttonClick:(id)sender
{
NSURL *url = [NSURL URLWithString:#"http://www.domain.com/page2/apa.html"];
NSURLRequest *theRequest = [NSURLRequest requestWithURL:url]
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if( theConnection )
{
webData = [[NSMutableData data] retain];
}
else
{
}
}
Then I monitor the response code in the didReceiveResponse method by casting the request to a NSHTTPURLResponse to be able to access the status codes and then setting a Bool depending on the status code.
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSHTTPURLResponse *ne = (NSHTTPURLResponse *)response;
if ([ne statusCode] == 200) {
ok = TRUE;
}
[webData setLength: 0];
}
I then check the bools value in connectionDidFinnishLoading. If I log the html NSString I get the source of the webpage so i know that it isn't an empty string.
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSString *html = [[NSString alloc] initWithBytes: [webData mutableBytes] length:[webData length] encoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:#"http://www.domain.com/"];
if (ok) {
[webView loadHTMLString:html baseURL:url];
ok = FALSE;
}
else {
// Create a new request to www.domain.com
}
}
webData is an instance variable and I load it in didReceiveData like this.
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[webData appendData:data];
}
I am assuming that webData is an instance variable on your class. I think your problem is that you are not setting webData to the data you are getting from the NSURLConnection. Try something like this:
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[webData appendData:data];
}
If that doesn't do the trick try adding an NSLog() after the NSString *html = [[NSString alloc]... line, like so:
NSLog(#"HTML: %#", html);
That will tell you whether you are getting HTML or not and whether the problem is with your NSURLConnection code or your UIWebView IBOutlet.
You are mixing two ways of performing connection - synchronous and asynchronous too. If the asynchronous finishes before the synchronous, you reinitialize webData to empty string. So even if synchronous populated webData it would be cleared.
// you create asynchronous connection which starts downloading in background immediately
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
// you create another synchronous connection which will block until the URL is downloaded
[NSURLConnection sendSynchronousRequest:theRequest returningResponse: &responseHeader error: nil];
// assuming your theRequest is valid, theConnection is always non-nil, so this is always TRUE
if (theConnection) {
// you reset content of webData, so if your synchronous connection has downloaded something, you throw it away here
webData = [[NSMutableData data] retain];
} else ...
Try to remove unnecessary/buggy call to sendSynchronousRequest:returningResponse:error: and it might work.
Anyway - where do you populate webData with data ? You did implement connection:didReceiveData: and append what comes into webData, right ? If you didn't - well, that's the problem you are seeing.

Making a request to a web service for logging purposes in Objective-C

I have a web service with a URL like this: http://webservice.com/?log=1
I would like to make a request to this URL in Objective-C such that the web service can log that fact. I don't care to pass anything on to the web service and nor do I care how it responds to the request.
What is the most effective way to achieve this?
The simplest way is to use the NSURLConnection sendSynchronousRequest:returningResponse:error: method.
e.g.
NSURLResponse *response;
[NSURLConnection sendSynchronousRequest: [NSURLRequest requestWithURL: [NSURL URLWithString: #"http://webservice.com/?log=1"]] returningResponse: &response error: NULL];
The downside to using this method is that it will hang your app while it's performing the URL request. To do this request asynchronously you need to use the connectionWithRequest:delegate: method. This gets a little more complex as you need to provide a delegate (in your case, one that does nothing).
e.g.
[[NSURLConnection connectionWithRequest: [NSURLRequest requestWithURL: [NSURL URLWithString: #"http://webservice.com/?log=1"]] delegate:self] retain];
...
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
[connection release];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[connection release];
}
See SimpleURLConnections for more examples of using NSURLConnection.
UPDATE: removed optional delagate methods as per David's comment.