[NSURLConnection sendAsynchronousRequest:request queue:queue
completionHandler:^(NSURLResponse *response,
NSData *data, NSError *connectionError) {}
How do I close NSURLConnection if I use sendAsynchronousRequest like that ?
You can use following method if you have NSURLConnection object
[conn cancel];
Where conn is the NSURLConnection object.
cancel is use to cancel asynchronous load of a request.
But in your case you dont have the object of connection so Please have a look
How can I cancel an asynchronous call through NSURLConnection sendAsynchronousRequest?
I hope this will help you.
Related
I am downloading some Images (approx 200-300 thumb images) on Using NSURLCOnnections. I have array of urls of these images. The connection starts to download these images. But in certain case i want to cancel all these downloading. How it is possible. Can i cancel all these NSURLConnections.
Will be better to create NSOperationQueue and work with NSURLConnection through this queue.
For example:
NSOperationQueue *queue = [NSOperationQueue new];
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:#selector(sendRequest)];
- (void) sendRequest {
NSURL *url = [NSURL URLWithString:#"http://www.google.com"];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
NSURLConnection *theConnection = [[[NSURLConnection alloc] initWithRequest:theRequest delegate:self] autorelease];
...
}
NSOperationQueue has method cancelAllOperations
[connection cancel] is used to cancel an NSURLConnection.
I would use a synchronous NSURLConnection in combination with an NSOperationQueue to download the data:
[queue addOperationWithBlock:^{
NSData *data = [NSURLConnection
sendSynchronousRequest:…
returningResponse:… error:…];
}];
This way you can easily control the number of concurrent downloads and cancel the unfinished ones using [queue cancelAllOperations]. Note that cancelling the queue won’t stop the downloads that have already started, but that won’t be a problem if you’re downloading just small thumbnails and have a decent concurrent download limit.
Synchronous NSURLConnection mode has the advantage of being much easier to use than the asynchronous delegation API.
I have created request as below,
NSURLResponse *response;
NSError *error;
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:JsonURL];
[request setTimeoutInterval:10];
[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
But here time out interval is not working,I checked some questions on stack some said default time out is 75 seconds and some said it's 240 seconds,I am confused here ..
please help me with this.
You are using a synchronous connection. So there will be no calls to a delegate. If you still want to use a synchrous URL request I would recommend the following:
[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
if (nil == response) {
if (error)
NSLog(#"Connection failed! Error - %# %#",
[error localizedDescription],
[[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]);
}
}
If you are want to use the delegate method you have to use an asynchronous request.
Please check the URL Loading System Programming Guide too.
I am using ASIHTTPRequest to send request to web server. It all works fine. But now, when i call the grabURLInBackground method, a request is sent to the given URL.
But now, i need to cancel the request (as in stop sending, and stop downloading the content from the URL), in the viewWillDissapear method. How can i do this ? Help
- (IBAction)grabURLInBackground:(id)sender
{
NSURL *url = [NSURL URLWithString:#"http://allseeing-i.com"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDelegate:self];
[request startAsynchronous];
}
- (void)requestFinished:(ASIHTTPRequest *)request
{
// Use when fetching text data
NSString *responseString = [request responseString];
// Use when fetching binary data
NSData *responseData = [request responseData];
}
- (void)requestFailed:(ASIHTTPRequest *)request
{
NSError *error = [request error];
}
for (ASIHTTPRequest *req in ASIHTTPRequest.sharedQueue.operations)
{
[req cancel];
[req setDelegate:nil];
}
this should cancel it..
You can do:
[request cancel]
Or:
[request clearDelegatesAndCancel];
As can be seen in the documentation here.
I'd suggest storing a reference to that request so you can cancel it when leaving the view.
GOt thsi from ASIHttp docs:
Cancelling an asynchronous request
To cancel an asynchronous request (either a request that was started with [request startAsynchronous] or a request running in a queue you created), call [request cancel]. Note that you cannot cancel a synchronous request.
Note that when you cancel a request, the request will treat that as an error, and will call your delegate and/or queue’s failure delegate method. If you do not want this behaviour, set your delegate to nil before calling cancel, or use the clearDelegatesAndCancel method instead.
// Cancels an asynchronous request
[request cancel]
// Cancels an asynchronous request,
clearing all delegates and blocks first
[request clearDelegatesAndCancel];When using an ASINetworkQueue, all other requests will be cancelled when you cancel an individual request unless the queue’s shouldCancelAllRequestsOnFailure is NO (YES is the default).
// When a request in this queue fails or is cancelled, other requests will continue to run
[queue setShouldCancelAllRequestsOnFailure:NO];
// Cancel all requests in a queue
[queue cancelAllOperations];
There are problems with using synchronous requests. The problem is that I am not really sure how to refactor the code below to use an asynchronous request to accomplish the following two tasks:
Use a UIActivityIndicatorView subview to notify of active fetching;
Implement a Reachability check before the connection request to ensure that there is an Internet connection and that the host is available, i.e. reachabilityWithHostName:#"wwww.mywebhostingisterrible.com".
Currently I have a Fetcher class with a +(Fetcher *)sharedFetcher singleton that is used in all of my view controllers to fetch data. Currently all data is fetched using the following code:
- (NSString *)stringWithUrl:(NSURL *)url {
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:30];
NSData *urlData;
NSURLResponse *response;
NSError *error;
urlData = [NSURLConnection sendSynchronousRequest:urlRequest
returningResponse:&response
error:&error];
return [[NSString alloc] initWithData:urlData encoding:NSUTF8StringEncoding];
}
A method that fetches looks like this:
-(NSArray *)fetchDogFoodListing {
NSString *urlString = [NSString stringWithFormat:#"%#query/dogFood/%#/%lli/%#/%#",self.connectionUrl,self.queryCriteria.dogFoodName,self.queryCriteria.dogFoodBrandId,self.queryCriteria.dogFoodIngredients,self.queryCriteria.dogFoodBrand];
NSString *json = [self stringWithUrl:[NSURL URLWithString:urlString]];
return [self.factory buildIKDogFoodArrayWithJSON:json];
}
and a call from the UIViewController in -(void)viewDidLoad looks like this:
self.dogFoods = [[IKFetcher sharedFetcher] fetchDogFoodListing];
I have thought about implementing a delegate in this situation but I am very shaky on how delegation ought to work. I'm not even sure which way it should go. Should the Fetcher have a FetcherDelegate that can notify the view controller of when it is done, so the UI can update? Should the view controller have a delegate so that the fetcher can update the view when stuff is done?
I'm sure based on my questions you can see my inexperience with delegation, so I would appreciate any help.
You could do something like this
dispatch_async(queue, ^{
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:30];
NSData *urlData;
NSURLResponse *response;
NSError *error;
urlData = [NSURLConnection sendSynchronousRequest:urlRequest
returningResponse:&response
error:&error];
dispatch_async(dispatch_get_main_queue(), ^{
//.. do stuff with data here...
}
}
or you could just do the sendSynchronousRequest code inside a dispatch_sync if you want the connection to be synchronous, though you should really should be as asynchronous as possible.
you may want to look at the brilliant framework by Mugunth Kumar:
http://blog.mugunthkumar.com/products/ios-framework-introducing-mknetworkkit
I plan on using this for NSURLConnection in my future projects
I have an API call. It takes more than 2 minute to get a response from the server. how can i abort it manually while it is processing?
Here is my code:
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
[request setTimeoutInterval: 600.0];
[request setHTTPMethod:#"GET"];
NSMutableDictionary* headers = [[[NSMutableDictionary alloc] init] autorelease];
[headers setValue:#"application/json" forKey:#"Content-Type"];
[headers setValue:#"application/json" forKey:#"Accept"];
[headers setValue:val forKey:#"Authorization"];
[request setAllHTTPHeaderFields:headers];
NSError *Error;
NSURLResponse *response = [[NSURLResponse alloc] init];
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&Error];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
how can i abort the request while its processing.
Thanks
You can't. Use asynchronous connections if you want to be able to cancel.
Also, BTW, you have some errors in your code:
NSError *Error;
NSURLResponse *response = [[NSURLResponse alloc] init];
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&Error];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
For good measure, Error should be initialized to nil.
You are leaking response. Initialize it to nil, and sendSynchronousRequest:returningResponse:error: will fill it in (if the request succeeds, anyway).
The line [[NSURLConnection alloc] initWithRequest:request delegate:self] starts an asynchronous connection and releases it, after you already did a synchronous connection for the same request. And it leaks the NSURLConnection object. Did you even implement the necessary methods for the informal delegate protocol on your self object?
You can't, as the thread is being blocked by your synchronous request.
synchronous load is built on top of the asynchronous loading code made available by the class. The calling thread is blocked while the asynchronous (sic) loading system performs the URL load on a thread spawned specifically for this load request.
http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSURLConnection_Class/Reference/Reference.html