在swift中上传图像AWS S3存储桶

时间:2016-10-31 18:53:15

标签: ios swift amazon-web-services amazon-s3

我正在尝试将图像上传到存储桶S3 AWS,我正在使用以下代码。但我是否使用它上传到存储在变量或imageView.image中的图像?

let ext = "jpg"
    let imageURL = NSBundle.mainBundle().URLForResource("imagename", withExtension: ext)
    print("imageURL:\(imageURL)")

    let uploadRequest = AWSS3TransferManagerUploadRequest()
    uploadRequest.body = imageURL
    uploadRequest.key = NSProcessInfo.processInfo().globallyUniqueString + "." + ext
    uploadRequest.bucket = S3BucketName
    uploadRequest.contentType = "image/" + ext


    let transferManager = AWSS3TransferManager.defaultS3TransferManager()
    transferManager.upload(uploadRequest).continueWithBlock { (task) -> AnyObject! in
        if let error = task.error {
            print("Upload failed ❌ (\(error))")
        }
        if let exception = task.exception {
            print("Upload failed ❌ (\(exception))")
        }
        if task.result != nil {
            let s3URL = NSURL(string: "http://s3.amazonaws.com/\(self.S3BucketName)/\(uploadRequest.key!)")!
            print("Uploaded to:\n\(s3URL)")
        }
        else {
            print("Unexpected empty result.")
        }
        return nil
    }

5 个答案:

答案 0 :(得分:8)

我修改了你的代码,试试这个

 let ext = "jpg"
let imageURL = NSBundle.mainBundle().URLForResource("imagename", withExtension: ext)
print("imageURL:\(imageURL)")

let uploadRequest = AWSS3TransferManagerUploadRequest()
uploadRequest.body = imageURL
uploadRequest.key = "\(NSProcessInfo.processInfo().globallyUniqueString).\(ext)"
uploadRequest.bucket = S3BucketName
uploadRequest.contentType = "image/\(ext)"


let transferManager = AWSS3TransferManager.defaultS3TransferManager()
transferManager.upload(uploadRequest).continueWithBlock { (task) -> AnyObject! in
if let error = task.error {
print("Upload failed ❌ (\(error))")
}
if let exception = task.exception {
print("Upload failed ❌ (\(exception))")
}
if task.result != nil {
let s3URL = NSURL(string: "http://s3.amazonaws.com/\(self.S3BucketName)/\(uploadRequest.key!)")!
print("Uploaded to:\n\(s3URL)")
}
else {
print("Unexpected empty result.")
}
return nil
}

或者您可以使用我的代码上传到AWS s3,它对我来说很好。此代码以swift 3编写。

func uploadButtonPressed(_ sender: AnyObject) {
if documentImageView.image == nil {
   // Do something to wake up user :) 
} else {
    let image = documentImageView.image!
    let fileManager = FileManager.default
    let path = (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString).appendingPathComponent("\(imageName!).jpeg")
    let imageData = UIImageJPEGRepresentation(image, 0.99)
    fileManager.createFile(atPath: path as String, contents: imageData, attributes: nil)

    let fileUrl = NSURL(fileURLWithPath: path)
    var uploadRequest = AWSS3TransferManagerUploadRequest()
    uploadRequest?.bucket = "BucketName"
    uploadRequest?.key = "key.jpeg"
    uploadRequest?.contentType = "image/jpeg"
    uploadRequest?.body = fileUrl as URL!
    uploadRequest?.serverSideEncryption = AWSS3ServerSideEncryption.awsKms
    uploadRequest?.uploadProgress = { (bytesSent, totalBytesSent, totalBytesExpectedToSend) -> Void in
        DispatchQueue.main.async(execute: {
            self.amountUploaded = totalBytesSent // To show the updating data status in label.
            self.fileSize = totalBytesExpectedToSend
        })
    }

    let transferManager = AWSS3TransferManager.default()
    transferManager?.upload(uploadRequest).continue(with: AWSExecutor.mainThread(), withSuccessBlock: { (taskk: AWSTask) -> Any? in
        if taskk.error != nil {
           // Error.
        } else {
            // Do something with your result.
        }
        return nil
    })
}
}

谢谢:)

答案 1 :(得分:2)

这是基于 SWIFT 4 语法

的最新代码

我正在使用@Karthick Selvaraj的代码。

我认为现在有助于其他开发人员理解新语法

func uploadButtonPressed() {
            if myimageView.image == nil {
                // Do something to wake up user :)
            } else {
                let image = myimageView.image!
                let fileManager = FileManager.default
                let path = (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString).appendingPathComponent("test3.jpeg")
                let imageData = UIImageJPEGRepresentation(image, 0)
                fileManager.createFile(atPath: path as String, contents: imageData, attributes: nil)

                let fileUrl = NSURL(fileURLWithPath: path)
                let uploadRequest = AWSS3TransferManagerUploadRequest()
                uploadRequest?.bucket = "<Your Bucket Name>"
                uploadRequest?.key = "<Image Name>"
                uploadRequest?.contentType = "image/jpeg"
                uploadRequest?.body = fileUrl as URL!
                uploadRequest?.serverSideEncryption = AWSS3ServerSideEncryption.awsKms
                uploadRequest?.uploadProgress = { (bytesSent, totalBytesSent, totalBytesExpectedToSend) -> Void in
                    DispatchQueue.main.async(execute: {
    //                    print("totalBytesSent",totalBytesSent)
    //                    print("totalBytesExpectedToSend",totalBytesExpectedToSend)

    //                    self.amountUploaded = totalBytesSent // To show the updating data status in label.
    //                    self.fileSize = totalBytesExpectedToSend
                    })
                }

                let transferManager = AWSS3TransferManager.default()
                transferManager.upload(uploadRequest!).continueWith(executor: AWSExecutor.mainThread(), block: { (task:AWSTask<AnyObject>) -> Any? in
                if task.error != nil {
                        // Error.
                    print("error")
                    } else {
                        // Do something with your result.
                    print("No error Upload Done")
                    }
                    return nil
                })
            }
        }

享受!!!

答案 2 :(得分:2)

AWSS3TransferManager已过时。请改用AWSS3TransferUtility

  

转移实用程序提供单部分方法和   分段上传。转移使用分段上传时,数据为   分块为多个5 MB的部分,这些部分并行传输   提高速度。

 func uploadFile(withImage image: UIImage) {

    let access = "YOUR ACCESS KEY"
    let secret = "YOUR SECRET KEY"
    let credentials = AWSStaticCredentialsProvider(accessKey: access, secretKey: secret)
    let configuration = AWSServiceConfiguration(region: AWSRegionType.USEast1, credentialsProvider: credentials)

    AWSServiceManager.default().defaultServiceConfiguration = configuration

    let s3BucketName = "YOUR BUCKET NAME"
    let compressedImage = image.resizedImage(newSize: CGSize(width: 80, height: 80))
    let data: Data = compressedImage.pngData()!
    let remoteName = generateRandomStringWithLength(length: 12)+"."+data.format
    print("REMOTE NAME : ",remoteName)

    let expression = AWSS3TransferUtilityUploadExpression()
    expression.progressBlock = { (task, progress) in
        DispatchQueue.main.async(execute: {
            // Update a progress bar
        })
    }

   var completionHandler: AWSS3TransferUtilityUploadCompletionHandlerBlock?
    completionHandler = { (task, error) -> Void in
        DispatchQueue.main.async(execute: {
            // Do something e.g. Alert a user for transfer completion.
            // On failed uploads, `error` contains the error object.
        })
    }

    let transferUtility = AWSS3TransferUtility.default()
    transferUtility.uploadData(data, bucket: s3BucketName, key: remoteName, contentType: "image/"+data.format, expression: expression, completionHandler: completionHandler).continueWith { (task) -> Any? in
        if let error = task.error {
            print("Error : \(error.localizedDescription)")
        }

        if task.result != nil {
            let url = AWSS3.default().configuration.endpoint.url
            let publicURL = url?.appendingPathComponent(S3BucketName).appendingPathComponent(remoteName)
            if let absoluteString = publicURL?.absoluteString {
                // Set image with URL
                print("Image URL : ",absoluteString)
            }
        }

        return nil
    }

}

用于为远程名称生成随机字符串。

func generateRandomStringWithLength(length: Int) -> String {
    let randomString: NSMutableString = NSMutableString(capacity: length)
    let letters: NSMutableString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
    var i: Int = 0

    while i < length {
        let randomIndex: Int = Int(arc4random_uniform(UInt32(letters.length)))
        randomString.append("\(Character( UnicodeScalar( letters.character(at: randomIndex))!))")
        i += 1
    }
    return String(randomString)
}

用于调整图像和数据格式的大小。使用下面的图像和数据扩展名。

extension UIImage {

  func resizedImage(newSize: CGSize) -> UIImage {
    guard self.size != newSize else { return self }

    UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0);
    self.draw(in: CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height))
    let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
    UIGraphicsEndImageContext()
    return newImage
   }

 }

extension Data {

  var format: String {
    let array = [UInt8](self)
    let ext: String
    switch (array[0]) {
    case 0xFF:
        ext = "jpg"
    case 0x89:
        ext = "png"
    case 0x47:
        ext = "gif"
    case 0x49, 0x4D :
        ext = "tiff"
    default:
        ext = "unknown"
    }
    return ext
   }

}

答案 3 :(得分:0)

这是使用AWS S3存储桶上传的图像,以下代码我实现了从图库上传到上传的图像

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject])
{
    if(picker.sourceType == UIImagePickerControllerSourceType.PhotoLibrary)
    {

        selectedImageUrl = info[UIImagePickerControllerReferenceURL] as! NSURL
        myImageViewC.image = info[UIImagePickerControllerOriginalImage] as? UIImage
        myImageViewC.backgroundColor = UIColor.clearColor()
        myImageViewC.contentMode = UIViewContentMode.ScaleAspectFit
        self.dismissViewControllerAnimated(true, completion: nil)
        startUploadingImage()
    }
    else  if(picker.sourceType == UIImagePickerControllerSourceType.Camera)
    {
        myImageViewC.image = info[UIImagePickerControllerOriginalImage] as? UIImage
        myImageViewC.backgroundColor = UIColor.clearColor()
        myImageViewC.contentMode = UIViewContentMode.ScaleAspectFit
        self.dismissViewControllerAnimated(true, completion: nil)


        myActivityIndicator.startAnimating()

        let S3BucketName = "streetsmartb2/sai"


        let date3 = NSDate()
        let timeInMi = "\(CLongLong((floor(date3.timeIntervalSince1970 * 1000))))"

        let S3UploadKeyName = "File.jpg\(timeInMi)"
        //print("value1:\(S3UploadKeyName)")

        //settings temp location for image
        let imageName = NSURL.fileURLWithPath(NSTemporaryDirectory() + S3UploadKeyName).lastPathComponent
        let documentDirectory = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first! as String
        // getting local path
        let localPath = (documentDirectory as NSString).stringByAppendingPathComponent(imageName!)
        //getting actual image
        let image = info[UIImagePickerControllerOriginalImage] as! UIImage
        //let data = UIImageJPEGRepresentation(image, 0.5)
        let data = CreateTeamViewController().resizeImage(image)
        data.writeToFile(localPath, atomically: true)
        //let imageData = NSData(contentsOfFile: localPath)!
        let photoURL = NSURL(fileURLWithPath: localPath)
        let uploadRequest = AWSS3TransferManagerUploadRequest()
        uploadRequest.body = photoURL
        uploadRequest.key = S3UploadKeyName
        uploadRequest.bucket = S3BucketName
        uploadRequest.contentType = "image/jpeg"

        let transferManager = AWSS3TransferManager.defaultS3TransferManager()

        // Perform file upload
        transferManager.upload(uploadRequest).continueWithBlock { (task) -> AnyObject! in

            if let error = task.error {
                print("Upload failed with error: (\(error.localizedDescription))")
                dispatch_async(dispatch_get_main_queue()) {
                    // self.returnToAddView()
                    self.myActivityIndicator.stopAnimating()
                    CreateTeamViewController().displayAlertMessage("Error uploading Image")
                }
            }
            if let exception = task.exception {
                print("Upload failed with exception (\(exception))")
                dispatch_async(dispatch_get_main_queue()) {
                    // self.returnToAddView()
                    self.myActivityIndicator.stopAnimating()
                    CreateTeamViewController().displayAlertMessage("Error uploading Image")
                }
            }

            if task.result != nil {
                // Remove locally stored file
                self.remoteImageWithUrl(uploadRequest.key!)
                let s3URL = NSURL(string: "https://s3.amazonaws.com/\(S3BucketName)/\(uploadRequest.key!)")!
             //   print("Uploaded to:\n\(s3URL)")
                dispatch_async(dispatch_get_main_queue()) {
                    // self.returnToAddView()
                    self.myActivityIndicator.stopAnimating()
                    self.createTeamImageButton?.setImage(self.loadImage, forState: .Normal)
                    self.uploadedImageURL = (s3URL.URLString)
                    //                        self.teamImageNameCreate = self.uploadedImageURL
                    //                        self.createTeamImageButton.sd_setImageWithURL(NSURL(string: self.uploadedImageURL)!, forState: .Normal, placeholderImage: UIImage(named: "no_image_one.jpg"))
                    let url = NSURL.init(string: self.uploadedImageURL)
                    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
                        // do some task
                        let imagedata  = NSData(contentsOfURL: url!)
                        if let imageObj = UIImage.init(data: imagedata!) {
                            self.createTeamPic = imageObj
                        }
                        dispatch_async(dispatch_get_main_queue()) {
                            self.createTeamImageButton?.setImage(self.createTeamPic, forState: .Normal)
                        }
                    }
                }
            }
            else {
              //  print("Unexpected empty result.")
            }
            return nil
        }
    }
}

答案 4 :(得分:0)

我们现在应该使用 AWSS3TransferUtility ,因为AWSS3TransferManagerUploadRequest已被弃用,这是 Swift 4.2 中的jpeg上传功能,但可以很容易地对其进行更改任何数据类型:

func uploadS3(image: UIImage,
              name: String,
              progressHandler: @escaping (Progress) -> Void,
              completionHandler: @escaping (Error?) -> Void) {

    guard let data = UIImageJPEGRepresentation(image, Constants.uploadImageQuality) else {
        DispatchQueue.main.async {
            completionHandler(NetErrors.imageFormatError) // Replace your error
        }
        return
    }

    let credentialsProvider = AWSStaticCredentialsProvider(accessKey: Constants.accessKeyS3, secretKey: Constants.secretKeyS3)
    let configuration = AWSServiceConfiguration(region: Constants.regionS3, credentialsProvider: credentialsProvider)
    AWSServiceManager.default().defaultServiceConfiguration = configuration
    let expression = AWSS3TransferUtilityUploadExpression()
    expression.progressBlock = { task, progress in
        DispatchQueue.main.async {
            progressHandler(progress)
        }
    }

    AWSS3TransferUtility.default().uploadData(
        data,
        bucket: Constants.bucketS3,
        key: name,
        contentType: "image/jpg",
        expression: expression) { task, error in
            DispatchQueue.main.async {
                completionHandler(error)
            }
            print("Success")

        }.continueWith { task -> AnyObject? in
            if let error = task.error {
                DispatchQueue.main.async {
                    completionHandler(error)
                }
            }
            return nil
    }
}

不要忘记在代码中定义或更改常量。如果您不想授予公共访问权限,则还应该在IAM中定义一个用户,并将此代码放入您的存储桶策略中:

{
  "Version": "2012-10-17",
  "Id": "S3AccessPolicy",
  "Statement": [
    {
      "Sid": "GiveAppAccess",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:user/YOUR_USER"
      },
      "Action": [
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Resource": "arn:aws:s3:::YOUR_BUCKET/*"
    }
  ]
}