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.
Related
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.
I want to download a document which i do it by following code
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:str] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:500];
[request setHTTPMethod:#"GET"];
NSData *returnData =[[NSURL alloc]init];
returnData=[NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
and depending on the data downloaded i want to show progress bar , is there any way how i can do that.
Thanks in advance.
In your delegate of NSURLConnection implement method - (void)connection:(NSURLConnection *)theConnection didReceiveResponse:(NSURLResponse *)response. In this method you can call
long long expLength = [response expectedContentLength];
In expLength you will have expected document size.
But be caution:
Some protocol implementations report the content length as part of the
response, but not all protocols guarantee to deliver that amount of
data. Clients should be prepared to deal with more or less data.
The NSURLConnection calls its delegate with
- (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;
Well, we need to look inside the NSURLResponse, to find the expectedContentLength
- (long long)expectedContentLength
Return Value The receiver’s expected content length,
or NSURLResponseUnknownLength if the length can’t be determined.
You can do it in either ways using Synchronous/Asynchronous call. For Asynchronous there delegate methods are there which you need to implement in your class and for Synchronous you can call it within your method scope.
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:.
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.
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.