I have implemented the usual Asynchronous connection mode in one of my apps and it works fine. The error handling is also happening properly. I also have implemented the Reachability API by Apple.
I would like to have for example 5 retires to be done when there is a network failure.
Kindly suggest me a good way to implement this.
Implementing the retry option was simple actually.
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
Use this method to make sure you identify the error condition while a try is failed. You can reinitiate the request again inside this method with a int flag has the NO_MAX_RETRY(eg.5) set.
- (void)connectionDidFinishLoading:(NSURLConnection *)connection this method when returned the connection is successful and you can reset the retry flag and release the retry routine.
Related
If I have installed a .pfx certificate in a mobileconfig, should I do something when the server ask for it, or does the system take care automatically of it?
Thanks
I'm not a big expert on this topic, but:
pfx certificates are supported for mobileconfig, as explained here, but I believe you have to implement a delegate of NSURLConnection in order to have the handshake done, i.e.
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
as already explained on this post.
Then you could take example from this post to find some useful code snippet.
You should declare the NSURLConnection delegates:
connection:didReceiveData,
connection:didReceiveResponse and
connectionDidFinishLoading.
I have designed an application which will download some data from the server, and all is working fine if there is no network issue. However if there is some network fluctuation during download some data will not be downloaded and the app will crash.
Here I need some help from you guys. Is it possible for me to write a separate code to handle such situation and re-download the entire data by deleting the incomplete downloaded data.
Thank you in advance,
Yes. you can do that.
There are two situation
1. Network not available.
- -> To fix this you have to use "Rechability" sample code(Provided by Apple). Before start downloading you have to check for internet availability.
- ->Or if you are not checking for internet rechability then you will got error code(404) in delegate method of NSURL connection:
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
2. Network Fluctuation.
Here I mean in between downloading if network fluctuate. Then it will call below method
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
You can handle all the things inside this method
When there is any network fluctuation or similar problem, you should get a HTTP error code if you are using NSURLConnection or any other network APIs. You could use that to delete the incomplete downloaded data and inform controller code so it could decide if to redownload etc.
Aditya is right. Assume that you are using NSURLConnection If your connection breaks you can read the response code using the following delegate method,
- (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response {
NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
int responseStatusCode = [httpResponse statusCode];
}
and you could proceed with stopping the connection and deleting your unfinished download data.
Updated answer for the comment.
If you are using different connections in different classes you should have this implemented in each of the classes. In my opinion you should have a design like in which a particular class will handle all connection related tasks. (May be it won't suit your requirement). But for your current design you should use this in all your classes.
I have an iPhone programming making many different NSURLConnections to a server. I use many different webservices, and for each I get a different response.
This means I make many different NSURL connections and I receive many different types of data back.
I have one class handling all my communications. i.e. one class with all the methods to access the webservices.
For every webservice I need to handle the data differently. As of now I have a saperate NSURLConnection delegate wich handles the:
-(void) connection:(NSURLConnection *) connection didReceiveResponse:(NSURLResponse *) response;
-(void) connection:(NSURLConnection *) connection didReceiveData:(NSData *) data;
-(void) connection:(NSURLConnection *) connection didFailWithError:(NSError *) error;
-(void) connectionDidFinishLoading:(NSURLConnection *) connection
functions. However, I want something different to be executed depending on the webservice I access.
Do I just need to make a different connection delegate for every webservice I want to handle?
Is there a better way to do this?
Thanks in advance.
You just need to examine the NSURLConnection that is passed into the method. That object corresponds to the connection which the method was tripped from, and you should be able to use that to figure out what web service it came from.
I'm writing a download manager in Objective-C, and I have it working with resume functionality. I am writing the data to disk as I receive it so that if the download is interrupted for any reason, it should pick up where it left off. Apple says you should expect one or more - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response events. In this event, they say you should reset any data you have previously received because your download is being redirected and the bytes you have already received is invalid, so I delete the existing file and recreate with 0 bytes. But if I receive this event multiple times, I have to delete data I have previously received in the form of a partial download, defeating the purpose of resume functionality. Is there a solution to this?
The solution I have come up with is: only reset the data on- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response events I receive after the first. This would fix the majority of cases (I would think). Is this logically sound? Is there a better alternative? How likely is a file download to fire multiple - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response events?
My recommendation would be to use a library from someone who has already solved this problem, ASIHttpRequest is what I use. It can be found here
Search for 'Resuming' on that page
multipart/x-mixed-replace is used when the server wants to replace what it has already given you with something else. Deleting everything you've downloaded so far is the only sensible option, you can't resume downloading something when the server is telling you to throw it away and use something else instead.
How likely is a file download to fire multiple - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response events?
Extremely unlikely. It's only ever used in certain types of streaming, not for anything you'd need a download manager for.
This is nice and clean library that, I think, has functionality that you need:
https://github.com/Anviking/DownloadManager
I have an app that uses ASI-HTTP-Request for large files, and I had a tester recently note that they wer observing very long loading delays that should be manifesting as timeouts. I have delegate methods wired up for request failures, but these didn't seem to be happening.
I poured through their documentation but didn't see anything specific.
In ASIHTTPRequest.m, look in the -checkRequestStatus method.
When a timeout occurs, the request fails with an ASIRequestTimedOutError error type:
[self failWithError:ASIRequestTimedOutError];
So you should be able to check the error returned in the delegate's -requestFailed: method:
- (void)requestFailed:(ASIHTTPRequest *)request {
NSLog(#"Error: %#",[[request error] localizedDescription]);
}
It's a good idea to read through the source to get a rough feel for how things work. The documentation is great, but not always in sync with the source code.