【问题标题】:S3 upload in AWS iOS SDK fails each timeAWS iOS SDK 中的 S3 上传每次都失败
【发布时间】:2016-03-22 08:31:32
【问题描述】:

尝试将图像上传到 s3,但每次都因未知原因失败。

private func uploadImageToS3(withS3Path s3path: String, image: UIImage, progress: (Float -> Void)?) -> BFTask{
    let path: NSString = NSTemporaryDirectory().stringByAppendingString("profile_image.jpg")
    let imageData = UIImageJPEGRepresentation(image, 0.8)
    imageData?.writeToFile(path as String, atomically: true)

    let url: NSURL = NSURL(fileURLWithPath: path as String)

    let uploadRequest = AWSS3TransferManagerUploadRequest()
    uploadRequest.bucket = "my_bucket"
    uploadRequest.key = s3path
    uploadRequest.contentType = "image/jpg"
    uploadRequest.body = url

    let transferManager = CognitoCredentialProvider.sharedInstance.s3TransferManager
    let completionSource = BFTaskCompletionSource()
    transferManager.upload(uploadRequest).continueWithExecutor(AWSExecutor.mainThreadExecutor(), withBlock: {(task:AWSTask!) in
        if task.error != nil{
            completionSource.setError(task.error!)
            return nil
        }else{
            completionSource.setResult(s3path)
        }
        return nil
    })
    return completionSource.task
}

上传开始,但在短时间内失败。日志:

进度 0.126221

进度 0.252442

进度 0.378663

进度 0.504884

AWSiOSSDKv2 [错误] AWSURLSessionManager.m 行:260 | -[AWSURLSessionManager URLSession:task:didCompleteWithError:] |会话任务失败并出现错误:Error Domain=NSURLErrorDomain Code=-1017“无法解析响应”UserInfo={NSUnderlyingError=0x7fda2f90e3c0 {Error Domain=kCFErrorDomainCFNetwork Code=-1017“(null)”UserInfo={_kCFStreamErrorCodeKey=-1, _kCFStreamErrorDomainKey=4 }}, NSErrorFailingURLStringKey=https://s3-us-west-2.amazonaws.com/my_bucket/profile_image/cognitoID/profile_image.jpg, NSErrorFailingURLKey=https://s3-us-west-2.amazonaws.com/my_bucket/profile_image/cognitoID/profile_image.jpg, _kCFStreamErrorDomainKey=4, _kCFStreamErrorCodeKey=-1, NSLocalizedDescription=无法解析响应}

传输管理器初始化:

 let kclIdentityProvider = KCLCognitoIdentityProvider(regionType: .USEast1, identityPoolId: "poolID", userSession: UserSession.sharedInstance)
    let cognitoCredProvider = AWSCognitoCredentialsProvider(regionType: .USEast1, identityProvider: kclIdentityProvider, unauthRoleArn: nil, authRoleArn: nil)
    self.credProvider = cognitoCredProvider
    let configuration = AWSServiceConfiguration(region: AWSRegionType.USEast1, credentialsProvider: cognitoCredProvider)
    AWSServiceManager.defaultServiceManager().defaultServiceConfiguration = configuration

    // s3, sns use uswest2
    let usWest2 = AWSServiceConfiguration(region: AWSRegionType.USWest2, credentialsProvider: self.credProvider)
    AWSS3TransferManager.registerS3TransferManagerWithConfiguration(usWest2, forKey: "USWest2S3")
    AWSSNS.registerSNSWithConfiguration(usWest2, forKey: "USWest2SNS")

    self.snsClient = AWSSNS(forKey: "USWest2SNS")
    self.s3TransferManager = AWSS3TransferManager.S3TransferManagerForKey("USWest2S3")

我能否以某种方式获得有关上传失败原因的更多信息?

【问题讨论】:

    标签: amazon-s3 aws-sdk aws-sdk-ios


    【解决方案1】:

    代码 -1017 表示服务器没有响应有效的 HTTP 响应。打开详细日志记录以获取更多信息:

        AWSLogger.defaultLogger().logLevel = .Verbose
    

    我使用以下内容上传到 S3:

    import AWSS3
    
    /** Schedule an upload request to S3 for a UIImage
        Parameter imageURL: NSURL to image location on the device
        Parameter imageName: string with image name
        Parameter imageFile: UIImage to be upload
        Parameter bucketName: string name of the bucket
        Return: AWSTask
    */
    func uploadImageToAWS (imageURL: NSURL, imageName: String, imageFile: UIImage, bucketName: String) -> AWSTask! {
        // create a file location for image
        UIImageJPEGRepresentation(imageFile, 1)!.writeToURL(imageURL, atomically: false)
    
        // save image
        let uploadRequest:AWSS3TransferManagerUploadRequest = AWSS3TransferManagerUploadRequest()
        uploadRequest.bucket = bucketName
        uploadRequest.key = imageName
        uploadRequest.body = imageURL
        uploadRequest.uploadProgress = { (bytesSent:Int64, totalBytesSent:Int64,  totalBytesExpectedToSend:Int64) -> Void in
            dispatch_sync(dispatch_get_main_queue(), {() -> Void in
                print(totalBytesSent)
            })
        }
    
        return AWSS3TransferManager.defaultS3TransferManager().upload(uploadRequest)
    }
    

    在我的 AppDelegate.swift 中:

    let credentialProvider = AWSCognitoCredentialsProvider(
            regionType: CognitoRegionType, identityPoolId: cognitoIdentityPoolId)        
    
    let configuration = AWSServiceConfiguration(
            region: DefaultServiceRegionType,
            credentialsProvider: credentialProvider)
    
    AWSServiceManager.defaultServiceManager().defaultServiceConfiguration = configuration
    

    然后在 IAM 的 AWS 控制台中,我使用策略生成器为 S3 存储桶创建角色策略 (Unauth)。看起来像这样:

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "Stmt123456789123",
                "Effect": "Allow",
                "Action": [
                    "s3:*"
                ],
                "Resource": [
                    "arn:aws:s3:::bucketname"
                ]
            }
        ]
    }
    

    最后,您需要在 S3 管理控制台中为存储桶权限添加存储桶策略:

    {
        "Version": "2012-10-17",
        "Id": "Policy1425419737188",
        "Statement": [
            {
                "Sid": "Stmt123456789123",
                "Effect": "Allow",
                "Principal": "*",
                "Action": "s3:*",
                "Resource": "arn:aws:s3:::bucketname/*"
            }
        ]
    }
    

    这可以通过以下方式生成:AWS Policy Generator

    【讨论】:

      猜你喜欢
      • 2017-04-12
      • 2014-11-15
      • 1970-01-01
      • 2021-01-10
      • 2016-10-08
      • 2022-11-03
      • 2022-08-20
      • 2021-04-20
      • 2018-12-31
      相关资源
      最近更新 更多