IOS Amazon S3 download large files

I'm new to Amazon S3, and it's hard for me to download large files from S3.

I successfully uploaded a 35 MB file every time, but when the file size is really big around 500 MB - 1.7 GB, the application crashes.

When I try a simulator, I get I can’t highlight a region error after about 1 GB of download.

So, I tried this on the device. Now it looks like it just crashes at random times and

the crash report does not fit into the device, so I have a problem debugging this problem.

At first I thought it was a device or even a simulator. But I'm not sure.

Someone mentioned that the S3 system occasionally accidentally downloads files for large files. Could this be so?

I create a file by opening a data file that is about to end, adding data, and then closing the file until the download is complete.

I am not sure how to debug this problem.

Any help would be appreciated.

Thank.

+3
source share
4 answers

S3GetObjectRequest has an NSMutableData * body, where it adds all the data it loads.

For large files, the data is constantly being added during the download process, and it goes through the VM limit of 90 MB, and then the application becomes killed by iOS.

A quick and dirty workaround is to create your own S3GetObjectRequest and S3GetObjectResponse classes. The AWS framework creates an instance of the response based on the name of the request class (the name of the request class without the last 7 characters is “request” and adds it using “Response” and tries to create a new class of this name).

- (void): (NSURLConnection *) didReceiveData: (NSData *) data​​strong > , .

, , , . , . 150-700 2,55 , +/- 0,2 .

ASIHTTP, .

- LargeFileS3GetObjectRequest.h

@interface LargeFileS3GetObjectRequest : S3GetObjectRequest
@end

- LargeFileS3GetObjectRequest.m

@implementation LargeFileS3GetObjectRequest
@end

- LargeFileS3GetObjectResponse.h

@interface LargeFileS3GetObjectResponse : S3GetObjectResponse
@end

- LargeFileS3GetObjectResponse.m

@implementation LargeFileS3GetObjectResponse

-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    // allow original implementation to send data to delegates
    [super connection:connection didReceiveData:data];

    // release body and set it to NULL so that underlying implementation doesn't
    // append on released object, but instead allocates new one
    [body release];
    body = NULL;
}
@end

, .

+1

AWS SDK iOS. S3GetObjectResponse, , .

S3GetObjectResponse.m

, :

NSOutputStream *outputStream = [[[NSOutputStream alloc] initToFileAtPath:FILE_NAME append:NO] autorelease];
[outputStream open];
S3GetObjectRequest *getObjectRequest = [[[S3GetObjectRequest alloc] initWithKey:FILE_NAME withBucket:BUCKET_NAME] autorelease];
getObjectRequest.outputStream = outputStream;
[s3 getObject:getObjectRequest];

. AWS AWS SDK iOS, , .

+3

You can transfer data to your application through ASIHTTPRequest

http://allseeing-i.com/ASIHTTPRequest/S3

NSString *secretAccessKey = @"my-secret-access-key";
NSString *accessKey = @"my-access-key";
NSString *bucket = @"my-bucket";
NSString *path = @"path/to/the/object";

ASIS3ObjectRequest *request = [ASIS3ObjectRequest requestWithBucket:bucket key:path];
[request setSecretAccessKey:secretAccessKey];
[request setAccessKey:accessKey];
[request startSynchronous];
if (![request error]) {
    NSData *data = [request responseData];
} else {
    NSLog(@"%@",[[request error] localizedDescription]);
}
0
source
/* Set up the Amazon client */
_s3 = [[AmazonS3Client alloc] initWithAccessKey:k_Amazon_ACCESS_KEY_ID withSecretKey:k_Amazon_SECRET_KEY];
_s3.endpoint = [AmazonEndpoints s3Endpoint:SA_EAST_1];

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{

    /* Open a file stream for the download */
    NSOutputStream *outputStream = [[NSOutputStream alloc] initToFileAtPath:[DOCUMENTS_DIRECTORY stringByAppendingPathComponent:k_Amazon_Video_Local_File_Name] append:NO];
    [outputStream open];

    /* Set up the s3 get object */

    S3GetObjectRequest *getVideoRequest = [[S3GetObjectRequest alloc] initWithKey:k_Amazon_Video_Path withBucket:@""];

    /* Set the stream */

    getVideoRequest.outputStream = outputStream;

    /* Get the response from Amazon */

    S3GetObjectResponse *getObjectResponse = [_s3 getObject:getVideoRequest];

    dispatch_async(dispatch_get_main_queue(), ^{

        if(getObjectResponse.error != nil)
        {
            NSLog(@"S3 Error: %@", getObjectResponse.error);
        }
        else
        {
            NSLog(@"S3 - Video download complete and successful");
            [[NSUserDefaults standardUserDefaults] setBool:YES forKey:k_Amazon_Video_Downloaded];
        }

        [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];

    });
});
0
source

All Articles