使用 Amazon Educate Starter 账户将图像上传到 S3

Posted

技术标签:

【中文标题】使用 Amazon Educate Starter 账户将图像上传到 S3【英文标题】:Upload image to S3 with Amazon Educate Starter Account 【发布时间】:2019-05-24 09:16:56 【问题描述】:

我只想将图像上传到 S3,但我正在使用 AWS Educate 帐户,并且我尝试了 4 个小时来完成此操作,并且对无法正常工作的问题有零想法。

所以我已经在 AWS 控制台上设置了所有内容,并且存储桶对每个人以及美国西弗吉尼亚州西部地区都是公共的,就像 AWS Educate 账户一样。

这是我的代码:

        let accessKey = "accessKey"
        let secretKey = "secretKey"
        let credentialsProvider = AWSStaticCredentialsProvider(accessKey: accessKey, secretKey: secretKey)
        let configuration = AWSServiceConfiguration(region: AWSRegionType.USEast1, credentialsProvider: credentialsProvider)
        AWSServiceManager.default().defaultServiceConfiguration = configuration

        let transferUtility = AWSS3TransferUtility.default()
        let bucketname = "bucketname"
        let expression = AWSS3TransferUtilityUploadExpression()

        transferUtility.uploadData(jpegData, bucket: bucketname, key: "myTransferUtilityUpload.jpg", contentType: "image/jpg", expression: expression)  (task, error) in
            if let error = error 
                print(error.localizedDescription)
            

            if let response = task.response 
                print(response)
            
        

谁能告诉我我做错了什么?

我收到此错误消息:

操作无法完成。 (com.amazonaws.AWSS3TransferUtilityErrorDomain 错误 2。)

accessKey + secretKey 我从“欢迎使用 AWS Educate Starter Account”仪表板上的 Account Details + AWS CLI 获得,显然存储桶名称与我的控制台中的名称相同

编辑:

if let jpegData = image.jpegData(compressionQuality: 0.7) 

        let fileManager = FileManager.default
        if let documentDirectory = fileManager.urls(for: .documentDirectory,
                                                    in: .userDomainMask).first 
            var sourceFolderURL =  documentDirectory.appendingPathComponent("image.jpg")

            do 
                try jpegData.write(to: sourceFolderURL)
             catch 
                print(error.localizedDescription)
                completionHandler(nil)
                return
            

            let accessKey = "-"
            let secretKey = "-"
            let bucketname = "-"
            let credentialsProvider = AWSStaticCredentialsProvider(accessKey: accessKey, secretKey: secretKey)
            let configuration = AWSServiceConfiguration(region: AWSRegionType.USEast1, credentialsProvider: credentialsProvider)
            AWSServiceManager.default().defaultServiceConfiguration = configuration


            let uploadRequest = AWSS3TransferManagerUploadRequest()!
            uploadRequest.body = sourceFolderURL
            uploadRequest.key = "image.jpg"
            uploadRequest.bucket = bucketname
            uploadRequest.contentType = "image/jpeg"
            uploadRequest.acl = .publicReadWrite

            let transferManager = AWSS3TransferManager.default()

            transferManager.upload(uploadRequest).continueWith  [weak self] (task) -> Any? in
                if let error = task.error 
                    print("Upload failed with error: (\(error.localizedDescription))")
                    completionHandler(nil)
                    return nil
                

                if task.result != nil 
                    let url = AWSS3.default().configuration.endpoint.url
                    let publicURL = url?.appendingPathComponent(uploadRequest.bucket!).appendingPathComponent(uploadRequest.key!)
                    if let absoluteString = publicURL?.absoluteString 
                        print("Uploaded to:\(absoluteString)")
                        completionHandler(nil)
                    
                
                completionHandler(nil)
                return nil
            
        
    

【问题讨论】:

如果这只是一次性需求,您可以使用AWS Command-Line Interface (CLI) aws s3 cp 命令上传文件。哦,桶也在 us-east-1 中吗? 是的,要使用 AWS Starter 账户,您只能使用 N. Virginia (USEast1) 使用 AWS CLI 复制文件是否有效?这将是一个很好的访问权限测试。 【参考方案1】:

我已使用以下代码将图像上传到 S3 存储桶: 首先,将图像保存到一个临时目录。

func uploadImageToS3(imageName:String, completion:@escaping (Bool) -> Void) 

    let accessKey = "accessKey"
    let secretKey = "secretKey"

    let credentialsProvider = AWSStaticCredentialsProvider(accessKey: accessKey, secretKey: secretKey)
    let configuration = AWSServiceConfiguration(region:AWSRegionType.APSoutheast2, credentialsProvider:credentialsProvider)

    AWSServiceManager.default().defaultServiceConfiguration = configuration

    let S3BucketName = "bucketname"

    let uploadRequest = AWSS3TransferManagerUploadRequest()!
    uploadRequest.body = self.getImageURLWithName(imageName:imageName)
    uploadRequest.key = "\(imageName)"
    uploadRequest.bucket = S3BucketName
    uploadRequest.contentType = "image/jpeg"

    //You can specify private or public here
    uploadRequest.acl = .private

    let transferManager = AWSS3TransferManager.default()

    transferManager.upload(uploadRequest).continueWith  [weak self] (task) -> Any? in
        ProgressIndicatorHelper.hideGlobalHUD()
        if let error = task.error 
            print("Upload failed with error: (\(error.localizedDescription))")
            completion(false)
        

        if task.result != nil 
            let url = AWSS3.default().configuration.endpoint.url
            let publicURL = url?.appendingPathComponent(uploadRequest.bucket!).appendingPathComponent(uploadRequest.key!)
            if let absoluteString = publicURL?.absoluteString 
                print("Uploaded to:\(absoluteString)")
                completion(true)
            
        

        return nil
    

为了从路径获取图像,我使用了以下代码:

 func getImageURLWithName(imageName:String) -> URL 
        var sourceImageURL: URL!
        let fileManager = FileManager.default
        if let documentDirectory = fileManager.urls(for: .documentDirectory,
                                                    in: .userDomainMask).first 
            var sourceFolderURL:URL!

            sourceFolderURL =  documentDirectory.appendingPathComponent("YourTempFolder")

            sourceImageURL = sourceFolderURL.appendingPathComponent(imageName)

        
        return sourceImageURL
    

希望这会有所帮助。

此外:目前我认为您不能直接从内存中上传图像。 我搜索了它。以下是相同的链接: https://github.com/aws-amplify/aws-sdk-ios/issues/42

How to upload a UIImage to S3 with AWS iOS SDK v2

如果您发现任何错误,请告诉我。

【讨论】:

因此,如果我将图像作为 UIImage/JPG 表示数据,您的意思是我应该将其保存到文件中,然后按照您的方式进行操作? 是的。我也这样做了。我分享了一些链接,人们在其中说无法上传记忆中的图像。您可以在继续之前参考这些链接。 是的,阅读它们,我会尝试一下,谢谢你,如果我(希望)成功完成,我会回来^^ 当然。如果您遇到任何问题,请告诉我 我只是使用了 AWSStaticCredentialsProvider() 而不是传递访问密钥和秘密密钥,并且知道它可以工作我很困惑,但无论它是否有效,都要感谢你。真的很感激。【参考方案2】:

也许这是一个政策问题? 尝试将此策略附加到您的存储桶(存储桶策略)


    "Version": "2012-10-17",
    "Statement": [
        
            "Effect": "Allow",
            "Action": [
                "s3:*"
            ],
            "Resource": [
                "arn:aws:s3:::mybucketname/*"
            ]
        
   ]

【讨论】:

要非常小心!这将使全世界都可以访问您的存储桶,包括上传和删除内容的权限。从安全和计费的角度来看,这不是一个好主意。 是的,我知道,但我的首要任务是让它现在工作,无论如何它只是用于培训目的,没有任何关键数据^^ 这只是为了测试目的,我应该说:)

以上是关于使用 Amazon Educate Starter 账户将图像上传到 S3的主要内容,如果未能解决你的问题,请参考以下文章

使用 python-amazon-mws API 的 Amazon Feed

是否可以使用 Amazon Cognito 组来设置对 AW 资源(例如 Amazon DynamoDB 和 Amazon S3)的权限?

如何使用 React-Starter-kit 安装 Reactstrap

记 SpringBoot starter的开发过程

在 Amazon S3 中托管静态网站而不使用 Amazon 路由 53

何时通过 AWS Glue ETL 使用 Amazon Redshift 频谱来查询 Amazon S3 数据