neilb
neilb

Reputation: 120

amazon s3 ios download progress bar

I am working on an iOS application that downloads images from amazon s3. I am trying to track progress of an image download.

I can not get the -(void)request:(AmazonServiceRequest *)request didSendData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite delegate method to fire.

This is the code that I have so far to set the delegate method.

-(void) viewDidLoad
{
self.s3 = [[AmazonS3Client alloc] initWithAccessKey:ACCESS_KEY_ID withSecretKey:SECRET_KEY];
self.s3.endpoint = [AmazonEndpoints s3Endpoint:US_WEST_2];

NSString *key = [[NSString alloc] initWithFormat:@"path1/%@", uniqueID];

S3GetObjectRequest *downloadRequest = [[S3GetObjectRequest alloc] initWithKey:key withBucket: PICTURE_BUCKET];
[downloadRequest setDelegate:self];

MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
hud.labelText = @"Loading Picture...";
S3GetObjectResponse *downloadResponse = [s3 getObject:downloadRequest];   
}

-(void)request:(AmazonServiceRequest *)request didSendData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite
{
NSLog(@"Bytes Written: %i", bytesWritten);
NSLog(@"Total Bytes Written: %i", totalBytesWritten);
NSLog(@"Total Bytes Expected to Write: %i", totalBytesExpectedToWrite);
}

I managed to get this delegate method to work for uploading images, but can not seem to get it to work for downloading. What do I need to do differently to track download progress?

Thanks

Upvotes: 1

Views: 1147

Answers (2)

Rafael Eyng
Rafael Eyng

Reputation: 4960

AdamG is right.

-(void)request:(AmazonServiceRequest *)request didSendData:(long long)bytesWritten totalBytesWritten:(long long)totalBytesWritten totalBytesExpectedToWrite:(long long)totalBytesExpectedToWrite is only for upload.

When you want to keep track of the progress of a download, you should use:

-(void)request:(AmazonServiceRequest *)request didReceiveData:(NSData *)data

And here I wan't to add some colaboration of my own. If you want to know the size of the file to download, here's a good way to do it.

S3GetObjectMetadataRequest *getMetadataObjectRequest = [[S3GetObjectMetadataRequest alloc] initWithKey:YOUR_KEY withBucket:YOUR_BUCKET]; S3GetObjectMetadataResponse *metadataResponse = [[AmazonClientManager s3] getObjectMetadata:getMetadataObjectRequest]; NSString *filesizeHeader = metadataResponse.headers[@"Content-Length"]; fileSize = [filesizeHeader floatValue];

I've found the documentation to be a little bit silent about this.

Also, the AWS iOS Samples also don't contain a very good example. Actually, there's a comment stating that "The progress bar for downlaod is just an estimate. In order to accurately reflect the progress bar, you need to first retrieve the file size", but without clue about how to do it.

So, I've found this way by messing around with the getMetadataObjectRequest.debugDescription property.

Hope this helps!

Upvotes: 1

AdamG
AdamG

Reputation: 3718

I came across this while researching myself on AWS and thought I would post an answer. -(void)request:(AmazonServiceRequest *)request didSendData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite only works when sending data, as per the name.

If you have a ballpark on how big the file is (you could set up some sort of server request to get this information before starting the download, or if there is a typical amount). Then you could use -(void)request:(AmazonServiceRequest *)request didReceiveData:(NSData *)data and continue to append the data to an @property of NSMutableData by calling [self.data appendData:data], then measure self.data.length which returns the number of bytes to your meta data size estimate which you could convert to bytes.

Hope this helps!

Upvotes: 3

Related Questions