如何使用AWS iOS SDK v2将UIImage上传到S3

Github中的README页面( https://github.com/aws/aws-sdk-ios-v2 )已经有一个上传图片的例子,从文件pathURL:

AWSS3TransferManagerUploadRequest *uploadRequest = [AWSS3TransferManagerUploadRequest new]; uploadRequest.bucket = yourBucket; uploadRequest.key = yourKey; uploadRequest.body = yourDataURL; // <<<< this is a NSURL uploadRequest.contentLength = [NSNumber numberWithUnsignedLongLong:fileSize]; 

但是,如果我只有一个UIImage在内存(没有文件path)? 是否可以使用SDK上传一个UIImage (或它的NSData )到S3

手动使用HTTP API(使用类似AFNetworking的)会更容易吗?

即使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; }]; 

看起来AWSiOSSDKv2目前不支持从内存上传图片:(

从Github的问题 :

只接受文件NSURLs的决定是由以下因素驱动的:

  1. 从v1开始,暂停/恢复function需要input文件。 当应用程序被终止时,不能恢复NSData并重试传输。
  2. iOS 7及以上版本的后台传输仅支持文件。 目前我们不支持后台迁移,但我们计划在未来支持。 我们考虑接受一个NSData并在内部持久化数据到一个临时目录。
  3. 我们决定不把它包含在2.0版本中,因为如果NSData是由文件支持的话,它会使数据的磁盘使用率翻倍。 另外,使用S3TransferManager时,开发人员必须处理与磁盘有关的错误。 尽pipe我们决定在2.0版本中不接受NSData,但我们愿意为您提供反馈。 如果这是您希望在未来版本中看到的function,请使用function请求创build一个新问题。

“`

你显然可以用“预先设定的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; }]; } 

http://docs.aws.amazon.com/mobile/sdkforios/developerguide/s3transfermanager.html#use-pre-signed-urls-to-transfer-objects-in-the-background中有关v2 SDK的S3文档

它与嵌套完成块有点混乱,但要点是你请求一个URL,然后当你返回时,你开始一个上传任务。 这是一个原型testing,而不是抛光代码。 您应该检查上传的状态代码,而不仅仅是错误。

这是一个更新的答案,所以人们不必自己弄清楚(像我一样):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; } 

我用一个button来知道用户何时想要上传文件

 - (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

YouTubevideo

希望这可以帮助别人!

嗨,你可以砂影像,而不保存图像到iPhone的临时文件夹亚马逊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"); } }