I need some help regarding the NSURLConnectionDelegate method.
- (void)startDownload {
NSString *URLString = [NSString stringWithFormat:appRecord.imageURLString];
NSURL *url = [NSURL URLWithString:URLString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
imageConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
if(imageConnection) {
activeDownload = [NSMutableData data];
}
}
I am using this method to initiate the NSURLConnection, but the
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
is not calling.. Need Help
Thanks in advance,
Shibin
No single answer but:
1) Put some NSLogs in to display the URL and then validate that it is generated correctly and does return data
2) Check that you have properly declared that you conform to the NSURLConnectionDelegate protocol in the .h
3) Are you threading or messing with the runloops ? " Messages to the delegate will be sent on the thread that calls this method. By default, for the connection to work correctly the calling thread’s run loop must be operating in the default run loop mode."
Sorry but do you do the start in your code ? I don't see it in your extract.
There should be a
[imageConnection start]
somewhere in your code to trigger the start of the connection and get your delegate called asynchronously.
Related
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.
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 wonder how I can check if a file exist on a server or not, without downloading the data first.
I have around 30 different objects and some of them is connected to a movie on a server. At the moment I use NSData to control if the the URL exist, and then shows the movie, or if it doesn't and then alerts the user that there is no video for that object. The code I use for the moment:
NSString *fPath = [[NSString alloc] initWithFormat:#"http://www.myserver/%#", [rows idNr]];
NSURL *videoURL = [NSURL URLWithString:fPath];
NSData *videoData = [NSData dataWithContentsOfURL:videoURL];
url = [NSURL URLWithString:fPath];
[fPath release];
if (videoData) {
[self performSelectorOnMainThread:#selector(playVideo:) withObject:url waitUntilDone:NO];
} else {
NSLog(#"videodata false");
errorLabel.hidden = NO;
activityView.hidden = YES;
}
"rows idNr" is the name of the object. This method is doing what I want, but the problem is that with NSData it first "downloading" the file, and when the URL is validated as a file, the movie is loading once again in the movieplayer. This means that it takes twice as long to load the file.
Suggestions?
It took me a while to dig out my answer to one of the previous questions on this topic. Quote:
You can use a NSMutableURLRequest to send a HTTP HEAD request
(there’s a method called setHTTPMethod). You’ll get the same
response headers as with GET, but you won’t have to download the whole
resource body. And if you want to get the data synchronously, use the
sendSynchronousRequest… method of NSURLConnection.
This way you’ll know if the file exists and won’t download it all if it does.
Make an URLConnecion object with desired url request and add NSURLConnectionDelegate into .h file like I want to check "yoururl" is exist or not then you need to do is
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString: #"http://www.google.com"]];
NSURLConnection *urlConnection = [[NSURLConnection alloc] initWithRequest:urlRequest delegate:self];
and then you can track http status code in delegate function of NSURLConnectionDelegate
-(void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
int code = [(NSHTTPURLResponse *)response statusCode];
if (code == 404)
{
// website not found
// do your stuff according to your need
}
}
You can also find various status code here.
NSError *err;
if ([videoURL checkResourceIsReachableAndReturnError:&err] == NO)
NSLog(#"wops!");
Here's the code for the accepted answer (for your convenience):
How to make call
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:#"HEAD"];
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
You could do this by checking the size of the file via an FTP server, using the SIZE command. If the file size is zero then the file simply do not exist.
Check here on how to do this.
You could of course also do this by using a NSURLRequest with NSURLConnection, checking for the status to be either 200 (success) or 404 (failed). The 404 status doesn't have to be that the file doesn't exist though, it could also be that the file just couldn't be retrieved.
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.