如何使用iOS相机上传到S3存储桶拍照

时间:2019-05-07 08:09:23

标签: ios swift amazon-s3 uiimageview

我正在尝试使用AWS S3 bucket存储用户从手机中拍摄照片时的照片。现在,我已经将代码设置为用户可以拍摄某些东西的照片,并将其显示在UIImageView上。

我遇到的问题是我不知道如何将其存储在S3存储桶中,我现在有代码可以存储指定存储桶中的照片,但实际上没有代码可以存储照片是从相机拍摄的。

拍摄照片代码

    @IBAction func takePhoto(_ sender: Any) {
        if UIImagePickerController.isSourceTypeAvailable(UIImagePickerController.SourceType.camera) {
            let imagePicker = UIImagePickerController()
            imagePicker.delegate = self
            imagePicker.sourceType = UIImagePickerController.SourceType.camera
            imagePicker.allowsEditing = false
            self.present(imagePicker, animated: true, completion: nil)

        }

    }
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        if let pickedImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
            takenPhoto.contentMode = .scaleToFill
            takenPhoto.image = pickedImage
            print(takenPhoto.image = pickedImage)
        }
        picker.dismiss(animated: true, completion: nil)



    }

AWS S3存储桶代码

    @IBAction func uploadFile(_ sender: Any) {
        uploadFile(with: "eartj", type: ".jpeg")

    }


    func uploadFile(with resource: String, type: String){
        let key = "\(resource),\(type)"
        let imagePath = Bundle.main.path(forResource: resource, ofType: type)!
        let imageUrl = URL(fileURLWithPath: imagePath)

        let request = AWSS3TransferManagerUploadRequest()!

        request.bucket = "wuuurktest"
        request.key = key
        request.body = imageUrl
        request.acl = .publicReadWrite

        let transferManager = AWSS3TransferManager.default()

        transferManager.upload(request).continueWith(executor: AWSExecutor.mainThread()) { (task) -> Any? in
            if let error = task.error {
                print(error)

            }

            if task.result != nil {
                print("Uploaded File")

            }

            return nil

        }

    }

链接到我用来创建文件上传的指南

https://www.youtube.com/watch?v=UMgApUhg7ic

3 个答案:

答案 0 :(得分:1)

您需要做的第一件事是将选择的图像作为临时文件存储在应用程序的文档目录中。拾取图像后,请使用以下功能将其保存到文档目录中。

func saveFileToDocumentDirectory(file: Data, fileExtension: String, folderName: String) -> URL? {

    let formatter = DateFormatter()
    formatter.dateFormat = "yyyyMMdd_HHmmss"
    let stringOfDateTimeStamp = formatter.string(from: Date())
    print("Date time stamp String: \(stringOfDateTimeStamp)")

    let directoryPath = (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString).appendingPathComponent("\(folderName)/")
    if !FileManager.default.fileExists(atPath: directoryPath) {
        do {
            try FileManager.default.createDirectory(at: NSURL.fileURL(withPath: directoryPath), withIntermediateDirectories: true, attributes: nil)
        } catch {
            print(error)
        }
    }
    let filename = "/\(stringOfDateTimeStamp)_\(fileExtension)"
    let customPath = "\(folderName)\(filename)"
    let filepath = directoryPath+filename
    print("FilePATH: \(filepath)")
    let url = NSURL.fileURL(withPath: filepath)
    do {
        try file.write(to: url, options: .atomic)
        print("CustomPAth:\(customPath)")
        print(String.init("\(directoryPath)\(filename)"))
        return url

    } catch {
        print(error)
        print("file cant not be save at path \(filepath), with error : \(error)");
        return nil
    }
}

这将返回一个URL,然后您可以使用以下功能将该文件上传到您的S3存储桶中。

func uploadToS3(url: URL, contentType: String, fileExtension: String){
    SwiftLoader.show(title: "Uploading File", animated: true)
    let accessKey = "YOUR_ACCESS_KEY"
    let secretKey = "YOUR_SECRET_KEY"
    let credentialsProvider = AWSStaticCredentialsProvider(accessKey: accessKey, secretKey: secretKey)
    let configuration = AWSServiceConfiguration(region: .USWest2, credentialsProvider: credentialsProvider)
    AWSServiceManager.default().defaultServiceConfiguration = configuration

    let remoteName = "IMG_\(UUID().uuidString)"+".\(fileExtension)"
    let S3BucketName = "YOUR_BUCKET_NAME"
    let uploadRequest = AWSS3TransferManagerUploadRequest()!
    uploadRequest.body = url
    uploadRequest.key = remoteName
    uploadRequest.bucket = S3BucketName
    uploadRequest.contentType = contentType
    uploadRequest.acl = .publicRead

    let transferManager = AWSS3TransferManager.default()
    transferManager.upload(uploadRequest).continueWith(block: { (task: AWSTask) -> Any? in
        if let error = task.error {
            print("Upload failed with error: (\(error.localizedDescription))")
            DispatchQueue.main.async {
                print("An error occurred while Uploading your file, try again.")
                SwiftLoader.hide()
            }
        }
        if task.result != nil {
            let url = AWSS3.default().configuration.endpoint.url
            let publicURL = url?.appendingPathComponent(uploadRequest.bucket!).appendingPathComponent(uploadRequest.key!)
            print("Uploaded to:\(String(describing: publicURL))")
        }
        return nil
    })
}

上传成功后,别忘了删除临时文件。

答案 1 :(得分:1)

嘿祖拜尔只使用下面的UIImage扩展名,我将其直接用于UIImage对象

 extension UIImage {

    //MARK: Uploading image function with S3 server...
    //MARK: ==========================================
    func uploadImageToS3(uploadFolderName: String = "",
                         compressionRatio : CGFloat = 1,
                         success : @escaping (Bool, String) -> Void,
                         progress : @escaping (CGFloat) -> Void,
                         failure : @escaping (Error) -> Void) {

        let name = "\(Int(Date().timeIntervalSince1970)).jpeg"
        let path = NSTemporaryDirectory().stringByAppendingPathComponent(path: name)

        //MARK: Compressing image before making upload request...
        guard let data = UIImageJPEGRepresentation(self, compressionRatio) else {
            let err = NSError(domain: "Error while compressing the image.", code : 01, userInfo : nil)
            failure(err)
            return
        }

        //MARK: Making upload request after image compression is done...
        guard let uploadRequest = AWSS3TransferManagerUploadRequest() else {

            let err = NSError(domain: "There is a problem while making the uploading request.", code : 02, userInfo : nil)
            failure(err)
            return
        }
        uploadRequest.bucket = "\(S3Details.bucketName)/\(S3Details.BUCKET_DIRECTORY)\(uploadFolderName.isEmpty ? "" : "/\(uploadFolderName)")"
        uploadRequest.acl    = AWSS3ObjectCannedACL.publicRead
        uploadRequest.key    = name

        try? data.write(to: URL(fileURLWithPath : path), options : .atomic)
        uploadRequest.body  = URL(fileURLWithPath: path)

        uploadRequest.uploadProgress = {(
            bytesSent : Int64,
            totalBytesSent : Int64,
            _ totalBytesExpectedToSend : Int64) -> Void in

            progress((CGFloat(totalBytesSent)/CGFloat(totalBytesExpectedToSend)))
                    print((CGFloat(totalBytesSent)/CGFloat(totalBytesExpectedToSend)))
        }

        AWSS3TransferManager.default().upload(uploadRequest).continueWith(executor: AWSExecutor.default()) { (task) -> Void in

            //MARK: That will remove image from temporary storage (NSTemporaryDirectory())...
            try? FileManager.default.removeItem(atPath : path)
            if let err = task.error {

                failure(err)
            } else {

                let imageURL = "\(S3Details.s3Url)\(S3Details.bucketName)/\(S3Details.BUCKET_DIRECTORY)\(uploadFolderName.isEmpty ? "" : "/\(uploadFolderName)")/\(name)"
                //                printDebug(imageURL)
                success(true, imageURL)
            }
        }
    }
  }

答案 2 :(得分:0)

以下是使用TransferUtility的示例:-

import AWSCognitoIdentityProvider
import AWSS3

typealias progressBlock = (_ progress: Double) -> Void
typealias completionBlock = (_ response: Any?, _ error: Error?) -> Void


//using Utility upload expression
func uploadImage(with image: URL, key: String?, progress: progressBlock?, completion: completionBlock?) {

    let expression = AWSS3TransferUtilityUploadExpression()
    expression.progressBlock = { (task: AWSS3TransferUtilityTask, awsProgress: Progress) -> Void in
        //print(awsProgress.fractionCompleted)
        guard let uploadProgress = progress else { return }
        DispatchQueue.main.async {
            uploadProgress(awsProgress.fractionCompleted)
        }
    }
    
    expression.setValue("public-read-write", forRequestHeader: "x-amz-acl")
    expression.setValue("public-read-write", forRequestParameter: "x-amz-acl")
    
    
    // Completion block
    var completionHandler: AWSS3TransferUtilityUploadCompletionHandlerBlock?
    completionHandler = { (task, error) -> Void in
        
        DispatchQueue.main.async(execute: {
            if error == nil {
                let url = AWSS3.default().configuration.endpoint.url
                let publicURL = url?.appendingPathComponent(AWS.bucketName).appendingPathComponent(key!)
                print("Uploaded to:\(String(describing: publicURL))")
                if let completionBlock = completion {
                    completionBlock(publicURL?.absoluteString, nil)
                }
            } else {
                if let completionBlock = completion {
                    completionBlock(nil, error)
                }
            }
        })
    }
    
    // Start uploading using AWSS3TransferUtility
    let awsTransferUtility = AWSS3TransferUtility.default()
    
    awsTransferUtility.uploadFile(
        image as URL,
        bucket: AWS.bucketName, //Make sure you write the correct bucket name here
        key: key!, //"private/{user_identity_id}/my-picture.png"
        contentType: "image/png",
        expression: expression,
        completionHandler: completionHandler).continueWith(block: { (task) -> Any? in
            
            if let error = task.error {
                print("error is: \(error.localizedDescription)")
                
            }
            if let _ = task.result {
                // your uploadTask
                print("Starting upload...")
            }
            
            return nil
        })
    
}

我传递的两个参数:-

image: URLkey: String?

这是我获取图像和图像名称(键)的方法:-

//setting temp name for upload // I am using a random string here
let imageName = "\(CommonMethod.randomString(length: 6))" + ".png"
            
//settings temp location for image
let tempDirectoryUrl = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(imageName)
guard let localUrlPath = image!.save(at: tempDirectoryUrl) else { return } 
//URL
print(localUrlPath)

祝您编程愉快!