Reputation: 1826
I'm trying to download a secure file from S3 server using NSURLSessionDownloadTask,but it returns me 403 error(Access Denied).
My Code:
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"https://xxx.amazonaws.com/bucket-name/file_name"]];
request.HTTPMethod = @"GET";
[request setValue:@"kAccessKey" forHTTPHeaderField:@"accessKey"];
[request setValue:@"kSecretKey" forHTTPHeaderField:@"secretKey"];
NSURLSessionDownloadTask *downloadPicTask = [[NSURLSession sharedSession] downloadTaskWithRequest:request completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
UIImage *downloadedImage = [UIImage imageWithData:
[NSData dataWithContentsOfURL:location]];
dispatch_async(dispatch_get_main_queue(), ^{
weakSelf.imageView.image = downloadedImage;
[weakSelf.activityIndicator stopAnimating];
});
}];
[downloadPicTask resume];
EDIT
I found this code :
AWSCognitoCredentialsProvider *credentialsProvider = [[AWSCognitoCredentialsProvider alloc]initWithRegionType:AWSRegionUSWest2 identityId:@"xxxxxxx" identityPoolId:@"xxxxxxxx" logins:nil];
AWSServiceConfiguration *configuration = [[AWSServiceConfiguration alloc]initWithRegion:AWSRegionUSWest2 credentialsProvider:credentialsProvider];
// Construct the NSURL for the download location.
NSString *downloadingFilePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"sample_img.png"];
NSURL *downloadingFileURL = [NSURL fileURLWithPath:downloadingFilePath];
// Construct the download request.
AWSS3TransferManagerDownloadRequest *downloadRequest = [[AWSS3TransferManagerDownloadRequest alloc]init];
AWSS3TransferManager * transferManager = [AWSS3TransferManager S3TransferManagerForKey:[[configuration credentialsProvider]sessionKey]];
downloadRequest.bucket = @"test-upload-bucket";
downloadRequest.key = @"sample_img.png";
downloadRequest.downloadingFileURL = downloadingFileURL;
[[transferManager download:downloadRequest] continueWithExecutor:[AWSExecutor mainThreadExecutor]
withBlock:^id(AWSTask *task){
return nil;
}];
What is the input value for IdentityId and IdentityPoolId ?
Upvotes: 3
Views: 5479
Reputation: 98
A working summer 2017 function, to which you can pass your image name and table cell (I'm downloading logos for certain table entries). Make sure you modify your credentials region, and your key/secret credentials, and your bucket name. Note: Your credentials should not be root. Create a separate IAM user/group/policy and authorize only specific resources (buckets/objects) and specific actions. Create your key and secret. I did this, because I do not want to use amazon's cogito to manage my users. but want my mobile app to access S3 resources directly and securely, and also not via a some redundant server-side script. But, Amazon recommends for mobile, you use cogito and have each user use own/temp creds. Caveat emptor.
-(void) awsImageLoad:(NSString*)imageFile :(UITableViewCell*)cell {
NSArray *filepathelements = [imageFile componentsSeparatedByString:@"/"];
if (filepathelements.count == 0) return;
//extract only the name from a possibe folder/folder/imagename
NSString *imageName = [filepathelements objectAtIndex:filepathelements.count-1];
AWSStaticCredentialsProvider *credentialsProvider =
[[AWSStaticCredentialsProvider alloc]
initWithAccessKey:@"_______________"
secretKey:@"__________________________________"];
//My credentials exist on the US East 1 region server farm
AWSServiceConfiguration *configuration = [[AWSServiceConfiguration alloc]initWithRegion:AWSRegionUSEast1 credentialsProvider:credentialsProvider];
// Construct the NSURL for the temporary download location.
NSString *downloadingFilePath = [NSTemporaryDirectory() stringByAppendingPathComponent:imageName];
NSURL *downloadingFileURL = [NSURL fileURLWithPath:downloadingFilePath];
// Construct the download request.
AWSS3TransferManagerDownloadRequest *downloadRequest = [AWSS3TransferManagerDownloadRequest new];
// S3 has only a Global Region -- establish our creds configuration
[AWSS3TransferManager registerS3TransferManagerWithConfiguration:configuration forKey:@"GlobalS3TransferManager"];
AWSS3TransferManager * transferManager = [AWSS3TransferManager S3TransferManagerForKey:@"GlobalS3TransferManager"];
downloadRequest.bucket = @"my_bucket_name";
downloadRequest.key = imageFile;
downloadRequest.downloadingFileURL = downloadingFileURL;
[[transferManager download:downloadRequest] continueWithExecutor:[AWSExecutor mainThreadExecutor] withBlock:^id(AWSTask *task){
if (task.error){
if ([task.error.domain isEqualToString:AWSS3TransferManagerErrorDomain]) {
switch (task.error.code) {
case AWSS3TransferManagerErrorCancelled:
case AWSS3TransferManagerErrorPaused:
break;
default:
NSLog(@"Error: %@", task.error);
break;
}
} else {
NSLog(@"Error: %@", task.error);
}
}
if (task.result) {
// ...this runs on main thread already
cell.imageView.image = [UIImage imageWithContentsOfFile:downloadingFilePath];
}
return nil;
}];
}
Upvotes: 5
Reputation: 166
All HTTP Request need to be properly signed before send to AWS server, the signing Process is very complicated Signature Version 4 Signing Process so I suggest to try AWS Mobile SDK for iOS v2
The example shown by Arun_ is a code snippets that how to use transferManager to download a file via AWS Mobile SDK for iOS v2.
Upvotes: 1
Reputation: 1826
This worked for me:
AWSStaticCredentialsProvider *credentialsProvider = [[AWSStaticCredentialsProvider alloc]initWithAccessKey:@"AccessKey" secretKey:@"secretKey"];
AWSServiceConfiguration *configuration = [[AWSServiceConfiguration alloc]initWithRegion:AWSRegionUSWest2 credentialsProvider:credentialsProvider];
// Construct the NSURL for the download location.
NSString *downloadingFilePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"sample_img.png"];
NSURL *downloadingFileURL = [NSURL fileURLWithPath:downloadingFilePath];
// Construct the download request.
AWSS3TransferManagerDownloadRequest *downloadRequest = [AWSS3TransferManagerDownloadRequest new];
[AWSS3TransferManager registerS3TransferManagerWithConfiguration:configuration forKey:@"USWest2S3TransferManager"];
AWSS3TransferManager * transferManager = [AWSS3TransferManager S3TransferManagerForKey:@"USWest2S3TransferManager"];
downloadRequest.bucket = @"test-upload-bucket";
downloadRequest.key = @"sample_img.png";
downloadRequest.downloadingFileURL = downloadingFileURL;
[[transferManager download:downloadRequest] continueWithExecutor:[AWSExecutor mainThreadExecutor]
withBlock:^id(AWSTask *task){
return nil;
}];
Upvotes: 0