Как загрузить UIImage на S3 с помощью AWS iOS SDK v2
На странице README в Github (https://github.com/aws/aws-sdk-ios-v2) уже есть пример загрузки изображения с URL-адреса пути к файлу:
AWSS3TransferManagerUploadRequest *uploadRequest = [AWSS3TransferManagerUploadRequest new];
uploadRequest.bucket = yourBucket;
uploadRequest.key = yourKey;
uploadRequest.body = yourDataURL; // <<<< this is a NSURL
uploadRequest.contentLength = [NSNumber numberWithUnsignedLongLong:fileSize];
Но что, если у меня есть только UIImage
в памяти (без пути к файлу)?
Можно ли загрузить UIImage
(или it NSData
) на S3
с помощью SDK
?
Было бы проще вручную использовать HTTP API (используя что-то вроде AFNetworking)?
Ответы
Ответ 1
Кажется, что AWSiOSSDKv2 не поддерживает загрузку изображений из памяти в данный момент: (
Из проблемы Github:
Решение о принятии только файлов NSURL было вызвано следующим факторы:
- Поскольку v1, функции паузы/возобновления требуют ввода файлы. Невозможно восстановить NSData и повторить передачу, если приложение убито.
- Фоновая передача только на iOS 7 и выше поддерживает файлы. В настоящее время мы не поддерживаем передачу фона, но мы планируем поддержать его в будущем. Мы решили принять NSData и внутренне сохраняя данные во временном каталоге.
- Мы решили не включать это в выпуск 2.0, потому что если NSData поддерживаемый файлом, он удваивает использование диска для данных. Также, разработчикам приходится иметь дело с дисковыми ошибками при использовании S3TransferManager. Хотя мы решили не принимать NSData в 2.0 релиз, мы открыты для ваших отзывов. Если это функция, которую вы хотите чтобы увидеть в будущем выпуске, пожалуйста, создайте новую проблему с помощью запрос функции.
`` `
Ответ 2
Несмотря на то, что AWSiOSSDKv2 не поддерживает загрузку изображений из памяти, вы можете сохранить его как файл и загрузить его.
//image you want to upload
UIImage* imageToUpload = [UIImage imageNamed:@"imagetoupload"];
//convert uiimage to
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *filePath = [[paths objectAtIndex:0] stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.png", dateKey]];
[UIImagePNGRepresentation(imageToUpload) writeToFile:filePath atomically:YES];
NSURL* fileUrl = [NSURL fileURLWithPath:filePath];
//upload the image
AWSS3TransferManagerUploadRequest *uploadRequest = [AWSS3TransferManagerUploadRequest new];
uploadRequest.body = fileUrl;
uploadRequest.bucket = AWS_BUCKET_NAME;
uploadRequest.key = @"yourkey";
uploadRequest.contentType = @"image/png";
[[transferManager upload:thumbNailUploadRequest] continueWithExecutor:[BFExecutor mainThreadExecutor] withBlock:^id(BFTask *task) {
if(task.error == nil) {
NSLog(@"woot");
}
return nil;
}];
Ответ 3
Вы можете сделать это с помощью "назначенных URL-адресов"
- (void)uploadImageToS3: (UIImage *)image {
NSData *imageData = UIImageJPEGRepresentation(image, 0.7);
AWSS3GetPreSignedURLRequest *getPreSignedURLRequest = [AWSS3GetPreSignedURLRequest new];
getPreSignedURLRequest.bucket = @"bucket-name";
getPreSignedURLRequest.key = @"image-name.jpg";
getPreSignedURLRequest.HTTPMethod = AWSHTTPMethodPUT;
getPreSignedURLRequest.expires = [NSDate dateWithTimeIntervalSinceNow:3600];
NSString *fileContentTypeString = @"text/plain";
getPreSignedURLRequest.contentType = fileContentTypeString;
[[[AWSS3PreSignedURLBuilder defaultS3PreSignedURLBuilder] getPreSignedURL:getPreSignedURLRequest] continueWithBlock:^id(AWSTask *task) {
if (task.error) {
NSLog(@"Error: %@", task.error);
} else {
NSURL *presignedURL = task.result;
NSLog(@"upload presignedURL is \n%@", presignedURL);
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:presignedURL];
request.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
[request setHTTPMethod:@"PUT"];
[request setValue:fileContentTypeString forHTTPHeaderField:@"Content-Type"];
NSURLSessionUploadTask *uploadTask = [[NSURLSession sharedSession] uploadTaskWithRequest:request fromData:imageData completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(@"Upload errer: %@", error);
}
NSLog(@"Done");
}];
[uploadTask resume];
}
return nil;
}];
}
Документировано в документах S3 для v2 SDK на http://docs.aws.amazon.com/mobile/sdkforios/developerguide/s3transfermanager.html#use-pre-signed-urls-to-transfer-objects-in-the-background
Немного беспорядок с вложенными блоками завершения, но суть в том, что вы запрашиваете URL-адрес, а затем, когда он возвращается, вы запускаете задачу загрузки. Это было для прототипа теста, а не для полированного кода. Вы должны проверить код состояния при загрузке, а не только на ошибку.
Ответ 4
Это обновленный ответ, поэтому люди не должны сами это понимать (например, я): D
Импортируйте нужные файлы (скачайте здесь)
#import <AWSCore/AWSCore.h>
#import <AWSS3TransferManager.h>
.m
- (void)viewDidLoad {
[super viewDidLoad];
AWSCognitoCredentialsProvider *credentialsProvider = [[AWSCognitoCredentialsProvider alloc] initWithRegionType:AWSRegionUSEast1
identityPoolId:@"us-east-1:*******-******-*****-*****-*****"];
AWSServiceConfiguration *configuration = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionUSEast1
credentialsProvider:credentialsProvider];
AWSServiceManager.defaultServiceManager.defaultServiceConfiguration = configuration;
}
Я использовал кнопку, чтобы узнать, когда пользователь хочет загрузить файл
- (void)upload{
//convert uiimage to
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *filePath = [[paths objectAtIndex:0] stringByAppendingPathComponent:[NSString stringWithFormat:@".png"]];
[UIImagePNGRepresentation(YOUR_UIIMAGE) writeToFile:filePath atomically:YES];
NSURL* fileUrl = [NSURL fileURLWithPath:filePath];
//upload the image
AWSS3TransferManagerUploadRequest *uploadRequest = [AWSS3TransferManagerUploadRequest new];
uploadRequest.body = fileUrl;
uploadRequest.bucket = @"YOUR_BUCKET_NAME";
uploadRequest.key = @"YOUR_FOLDER_NAME (if you have one)/NEW_IMAGE_NAME.png";
uploadRequest.contentType = @"image/png";
uploadRequest.ACL = AWSS3BucketCannedACLPublicRead;
AWSS3TransferManager *transferManager = [AWSS3TransferManager defaultS3TransferManager];
[[transferManager upload:uploadRequest] continueWithExecutor:[AWSExecutor mainThreadExecutor]
withBlock:^id(AWSTask *task) {
if (task.error != nil) {
NSLog(@"%s %@","Error uploading :", uploadRequest.key);
}else { NSLog(@"Upload completed"); }
return nil;
}];
}
Полезные ссылки:
AWS Documnetion
Видео YouTube
Надеюсь, это поможет кому-то!
Ответ 5
Привет, вы можете сфотографировать изображение без сохранения изображения во временную папку на iPhone. Amazon iOS v2 также предоставляет такую возможность.
В этом коде logFile.body
это NSData
.
Этот код поможет вам, мой друг.
AWSS3PutObjectRequest *logFile = [AWSS3PutObjectRequest new];
logFile.bucket = uploadTokenData_.bucket;
logFile.key = key;
logFile.contentType = contentType;
logFile.body = data_;
logFile.contentLength = [NSNumber numberWithInteger:[data_ length]];
AWSS3 *S3 = [[AWSS3 alloc] initWithConfiguration:[AWSCredentialsProvider runServiceWithStsCredential]];
AWSS3TransferManager *transferManager = [[AWSS3TransferManager alloc] initWithS3:S3];
[[transferManager.s3 putObject:logFile] continueWithBlock:^id(BFTask *task)
{
NSLog(@"Error : %@", task.error);
if (task.error == nil)
{
NSLog(@"Uploadet");
}
}