How to Resolve Image Upload Error Using AWS on iOS
I am following this tutorial which involves loading a UIImage into an s3 bucket using cognito for authentication. I can connect to cognito because my device shows up in the ID pool. However, when I try to load the image into the bucket, I get this error:
Error Domain=com.amazonaws.AWSGeneralErrorDomain Code=3 "The request signature we calculated does not match the signature you provided. Check your key and signing method." UserInfo=0x17dc0f40 {NSLocalizedDescription=The request signature we calculated does not match the signature you provided. Check your key and signing method.}
The cognito authentication policy is as follows:
{
"Version": "2012-10-17",
"Statement": [{
"Action": [
"mobileanalytics:PutEvents",
"cognito-sync:*",
"s3:*"
],
"Effect": "Allow",
"Resource": [
"*"
]
}]
}
The code for setting up credentials looks like this:
AWSCognitoCredentialsProvider *credentialsProvider = [AWSCognitoCredentialsProvider
credentialsWithRegionType:AWSRegionUSEast1
accountId:@"#######"
identityPoolId:@"######"
unauthRoleArn:@"#####"
authRoleArn:@"######"];
AWSServiceConfiguration *configuration = [AWSServiceConfiguration configurationWithRegion:AWSRegionUSEast1
credentialsProvider:credentialsProvider]
and the code to load the image in s3 looks like this:
NSString *tempPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"image.png"];
NSData *imageData = UIImagePNGRepresentation(image);
[imageData writeToFile:tempPath atomically:YES];
NSURL *url = [[NSURL alloc] initFileURLWithPath:tempPath];
AWSS3TransferManagerUploadRequest *uploadRequest = [AWSS3TransferManagerUploadRequest new];
uploadRequest.bucket = @"##########";
//uploadRequest.ACL = AWSS3ObjectCannedACLPublicRead;
uploadRequest.key = @"image.png";
//uploadRequest.contentType = @"image/png";
uploadRequest.body = url;
uploadRequest.uploadProgress =^(int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend){
dispatch_sync(dispatch_get_main_queue(), ^{
});
};
AWSS3TransferManager *transferManager = [AWSS3TransferManager defaultS3TransferManager];
[[transferManager upload:uploadRequest] continueWithExecutor:[BFExecutor mainThreadExecutor] withBlock:^id(BFTask *task) {
if (task.error) {
NSLog(@"%@", task.error);
}else{
//success
NSLog(@"success");
[[NSFileManager defaultManager] removeItemAtURL:url error:nil];
}
return nil;
}];
+3
source to share
1 answer
Below is the code for uploading the image to amazon s3 and also the description that follows step by step.
- (void)uploadToS3{
// get the image from a UIImageView that is displaying the selected Image
UIImage *img = _selectedImage.image;
// create a local image that we can use to upload to s3
NSString *path = [NSTemporaryDirectory() stringByAppendingPathComponent:@"image.png"];
NSData *imageData = UIImagePNGRepresentation(img);
[imageData writeToFile:path atomically:YES];
// once the image is saved we can use the path to create a local fileurl
NSURL *url = [[NSURL alloc] initFileURLWithPath:path];
// next we set up the S3 upload request manager
_uploadRequest = [AWSS3TransferManagerUploadRequest new];
// set the bucket
_uploadRequest.bucket = @"s3-demo-objectivec";
// I want this image to be public to anyone to view it so I'm setting it to Public Read
_uploadRequest.ACL = AWSS3ObjectCannedACLPublicRead;
// set the image name that will be used on the s3 server. I am also creating a folder to place the image in
_uploadRequest.key = @"foldername/image.png";
// set the content type
_uploadRequest.contentType = @"image/png";
// we will track progress through an AWSNetworkingUploadProgressBlock
_uploadRequest.body = url;
__weak ViewController *weakSelf = self;
_uploadRequest.uploadProgress =^(int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend){
dispatch_sync(dispatch_get_main_queue(), ^{
weakSelf.amountUploaded = totalBytesSent;
weakSelf.filesize = totalBytesExpectedToSend;
[weakSelf update];
});
};
// now the upload request is set up we can creat the transfermanger, the credentials are already set up in the app delegate
AWSS3TransferManager *transferManager = [AWSS3TransferManager defaultS3TransferManager];
// start the upload
[[transferManager upload:_uploadRequest] continueWithExecutor:[BFExecutor mainThreadExecutor] withBlock:^id(BFTask *task) {
// once the uploadmanager finishes check if there were any errors
if (task.error) {
NSLog(@"%@", task.error);
}else{// if there aren't any then the image is uploaded!
// this is the url of the image we just uploaded
NSLog(@"https://s3.amazonaws.com/s3-demo-objectivec/foldername/image.png");
}
return nil;
}];
}
0
source to share