如何使用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的决定是由以下因素驱动的:
- 从v1开始,暂停/恢复function需要input文件。 当应用程序被终止时,不能恢复NSData并重试传输。
- iOS 7及以上版本的后台传输仅支持文件。 目前我们不支持后台迁移,但我们计划在未来支持。 我们考虑接受一个NSData并在内部持久化数据到一个临时目录。
- 我们决定不把它包含在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; }]; }
它与嵌套完成块有点混乱,但要点是你请求一个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"); } }