Buscar..


Suba una imagen o un video a S3 usando AWS SDK

Antes de comenzar con el ejemplo, recomendaría crear un Singleton con un miembro de la clase delegado para poder utilizar un archivo en segundo plano y dejar que el usuario siga usando su aplicación mientras los archivos se cargan, incluso cuando la aplicación es el fondo

Comencemos, primero, debemos crear una enumeración que represente la configuración de S3:

enum S3Configuration : String
{
    case IDENTITY_POOL_ID   = "YourIdentityPoolId"
    case BUCKET_NAME        = "YourBucketName"
    case CALLBACK_KEY       = "YourCustomStringForCallBackWhenUploadingInTheBackground"
    case CONTENT_TYPE_IMAGE = "image/png"
    case CONTENT_TYPE_VIDEO = "video/mp4"
}

Ahora, deberíamos establecer las credenciales cuando su aplicación se inicie por primera vez, por lo tanto, debemos configurarlas dentro de AppDelegate en el método didFinishLaunchingWithOptions (preste atención a que debe establecer su región en el regionType ):

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool
{
  let credentialProvider = AWSCognitoCredentialsProvider(regionType: .EUWest1, identityPoolId: S3Configuration.IDENTITY_POOL_ID.rawValue)
  let configuration = AWSServiceConfiguration(region: .EUWest1, credentialsProvider: credentialProvider)
  AWSS3TransferUtility.registerS3TransferUtilityWithConfiguration(configuration, forKey: S3Configuration.CALLBACK_KEY.rawValue)
}

Como ya estamos dentro de AppDelegate, deberíamos implementar la devolución de llamada en segundo plano que maneja el SDK de AWS:

func application(application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: () -> Void)
{
    //  Will print the identifer you have set at the enum: .CALLBACK_KEY
    print("Identifier: " + identifier)
    //  Stores the completion handler.
    AWSS3TransferUtility.interceptApplication(application,
                                              handleEventsForBackgroundURLSession: identifier,
                                              completionHandler: completionHandler)
}

Ahora, cuando el usuario mueva la aplicación al fondo, su carga continuará con la carga real.

Para cargar el archivo con el SDK de AWS, tendremos que escribir el archivo en el dispositivo y darle a la SDK la ruta real. Por el bien del ejemplo, imagine que tenemos un UIImage (también podría ser un video ...) y lo escribiremos en una carpeta temporal:

// Some image....
let image = UIImage()
let fileURL = NSURL(fileURLWithPath: NSTemporaryDirectory()).URLByAppendingPathComponent(fileName)
let filePath = fileURL.path!
let imageData = UIImageJPEGRepresentation(image, 1.0)
imageData!.writeToFile(filePath, atomically: true)

FileURL y fileName se utilizarán para la carga real más adelante.

Hay 2 cierres que tendremos que definir que son proporcionados por el SDK de AWS,

  1. AWSS3TransferUtilityUploadCompletionHandlerBlock : un cierre que notifica cuando se realiza la carga (o no)
  2. AWSS3TransferUtilityUploadProgressBlock : un cierre que notifica cada byte enviado

Si planea tener un Singleton debe definir esos tipos como miembros de la clase. La implementación debería verse así:

var completionHandler : AWSS3TransferUtilityUploadCompletionHandlerBlock? =
    { (task, error) -> Void in

        if ((error) != nil)
        {
          print("Upload failed")
        }
        else
        {
          print("File uploaded successfully")
        }
    }

var progressBlock : AWSS3TransferUtilityUploadProgressBlock? = 
    { [unowned self] (task, bytesSent:Int64, totalBytesSent:Int64,  totalBytesExpectedToSend:Int64) -> Void in

     let progressInPercentage = Float(Double(totalBytesSent) / Double(totalBytesExpectedToSend)) * 100
     print(progressInPercentage)
    }

NOTA: Si está utilizando un Singleton, es posible que desee definir un delegado que informará sobre el progreso o cuando se complete el archivo. Si no está utilizando un Singleton, puede crear un método estático que tenga los tipos relevantes:

    static func uploadImageToS3(fileURL : NSURL,
                               fileName : String,
                progressFunctionUpdater : Float -> Void,
                            resultBlock : (NSError?) -> Void)
{
 //    Actual implementation .....
 //    ...
 //    ...
}
  1. progressFunctionUpdater : informará a una función con progreso.
  2. resultBlock : si devuelve nil, la carga se realizó con éxito, envía el objeto de error

Señoras y señores, la carga real:

        let fileData = NSData(contentsOfFile: fileURL.relativePath!)

        let expression = AWSS3TransferUtilityUploadExpression()
        expression.uploadProgress = progressBlock
        
        let transferUtility = AWSS3TransferUtility.S3TransferUtilityForKey(S3Configuration.CALLBACK_KEY.rawValue)
        
        transferUtility?.uploadData(fileData!,
            bucket: S3Configuration.BUCKET_NAME.rawValue,
            key: fileName,
            contentType: S3Configuration.CONTENT_TYPE_IMAGE.rawData,
            expression: expression,
            completionHander: completionHandler).continueWithBlock
            { (task : AWSTask) -> AnyObject? in
                
                if let error = task.error
                {
                    print(error)
                }
                if let exception = task.exception
                {
                    print("Exception: " + exception.description)
                }
                if let uploadTask = task.result as? AWSS3TransferUtilityUploadTask
                {
                    print("Upload started...")
                }
                
                return nil
        }

Feliz S3 subiendo :)



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow