3
votes

Comment télécharger dans le compartiment S3 en prenant une photo avec l'appareil photo iOS

J'essaie d'utiliser le compartiment AWS S3 pour stocker les photos des utilisateurs à partir de quand ils les ont prises sur leur téléphone. J'ai actuellement mon code configuré au point où l'utilisateur peut prendre une photo de quelque chose et l'afficher sur UIImageView .

Le problème que je rencontre est que j'ai Je n'ai aucune idée de comment le stocker sur le compartiment S3, j'ai actuellement du code capable de stocker une photo spécifiée dans le compartiment, mais pas vraiment du code capable de stocker une photo prise depuis l'appareil photo.

Code de prise de photo
    @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

        }

    }

Code de compartiment AWS 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)



    }

Lien vers le guide que j'utilise pour créer le téléchargement du fichier

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


0 commentaires

3 Réponses :


2
votes

La première chose à faire est de stocker l'image sélectionnée dans le répertoire de documents de votre application en tant que fichier temporaire. Dès que votre image est sélectionnée, enregistrez-la dans le répertoire du document en utilisant la fonction ci-dessous.

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
    })
}

Cela renverra une URL et vous pourrez ensuite utiliser la fonction ci-dessous pour télécharger ce fichier sur votre S3 bucket.

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
    }
}

N'oubliez pas de supprimer votre fichier temporaire une fois le téléversement réussi.


2 commentaires

Existe-t-il un moyen de l'enregistrer sans l'enregistrer temporairement après avoir pris la photo avec l'appareil photo?


Il pourrait y en avoir, je ne peux pas vous dire avec certitude. Mais j'ai essayé beaucoup de méthodes différentes, et cela a parfaitement fonctionné pour moi. Dans mon cas, j'avais plusieurs types de fichiers tels que les fichiers audio, vidéo, images et documents. Donc, mon approche ici est plus généralisée. J'appelle cette même fonction pour télécharger n'importe quel type de fichier sur S3. D'après mes recherches, je pense qu'il est nécessaire de le stocker temporairement, car vous transmettez l'URL du fichier à S3 en tant que corps .



2
votes

Hé Zubair, utilisez juste ci-dessous l'extension UIImage que j'ai créée fonctionnera directement dans l'objet 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)
            }
        }
    }
  }


3 commentaires

Hé Shivam, serait-il important que j'utilise une UIImageView?


vous pouvez obtenir une image à partir d'imageview en utilisant également imageview.image, donc oui, vous pouvez l'utiliser, mais dans pickerController, vous obtenez une utilisation d'image en téléchargement là-bas, je ne sais pas votre cas d'utilisation, mais vous pouvez également l'utiliser sur imageview, j'espère que cela aide :)


Il indique que 'AWSS3TransferManager' est obsolète: utilisez `AWSS3TransferUtility` pour les opérations de chargement et de téléchargement. . Pouvez-vous mettre à jour cette réponse pour le dernier SDK S3?



0
votes

Voici un exemple utilisant TransferUtility:-

//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)

Deux paramètres que je passe: -

image: URL et key: String?

Voici comment j'obtiens l'image et le nom de l'image (clé): -

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
        })
    
}

Bon codage!


0 commentaires