objective-ciosdownloadresume-download

Downloading a file using NSURLConnection?


I have an API that gets me the file URL to download. I am using NSURLConnection to download the file. The file size could be a little big because it's an MP4.

Code Steps:

  1. Initialized NSMutableURLRequest and added HttpHeaderField to it with the byte index I want to resume download from. (I do this because internet connection could be lost).

  2. Initialized NSURLConnection with the NSMutableURLRequest.

  3. Used connection:didReceiveData: to receive data segments and append it to a global NSMutableData object.

  4. An error message could be generated because of an internet problem and it's handled using connection:didFailWithError:. In this handler I setText the download status label with the message "No internet connectivity, or it is very slow". Sleep for 1 second and then go back to step one again.

Code:

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self resumeDownload];
}

- (void)resumeDownload
{
    NSURL *url = [NSURL URLWithString:video->videoUrl];
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
    if (receivedData==nil)
    {
        receivedData = [[NSMutableData alloc] init];
    }
    else
    {
        NSString *range = [NSString stringWithFormat:@"bytes=%i-", receivedData.length];
        [request setValue:range forHTTPHeaderField:@"Range"];
    }

    downloadConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    NSLog(@"%@", [response description]);
}

- (void) connection:(NSURLConnection*)connection didFailWithError:(NSError*) error
{
    NSLog(@"Download Fail : %d", [error code]);
    [status setText:@"No internet conectivity or it is very slow."];
    sleep(1);
    [self resumeDownload];
}

- (void) connectionDidFinishLoading:(NSURLConnection*)connection
{
    // save the file
}

- (void) connection: (NSURLConnection*) connection didReceiveData: (NSData*) data
{
    if(connection == downloadConnection)
    {
        [receivedData appendData:data];
        [status setText:[NSString stringWithFormat:@"Downloading: %d Bytes.", receivedData.length]];
    }
}

Screen Shots:

enter image description here enter image description here

Note: When the internet reconnects, the download will resume automatically.

Is this a proper solution for the problem?


Solution

  • All in all - you're on the right path.
    You should check the kind of errors you get - if there's no network, there's no point trying again, you should use a reachability test to find out when to try again.
    You should also check the response type - 4xx / 5xx will not return a connection failure even though this is a failure for you, for example - 502 error means you should try a bit later, even though the connection finished successfully.
    I'd avoid using sleep - you're blocking the main thread.
    Either use performSelector:withObject:afterDelay or use an NSTimer.
    Oh, and one second seems too short to me.