Uso del almacenamiento de blobs desde iOS

En este artículo se muestran escenarios comunes con Microsoft Azure Blob Storage. Los ejemplos están escritos en Objective-C y usan la Biblioteca del cliente de Azure Storage para iOS. Entre los escenarios descritos se incluyen cargar, enumerar, descargar y eliminar blobs. Para obtener más información acerca de los blobs, consulte la sección Pasos siguientes . También puede descargar la aplicación de ejemplo para ver rápidamente el uso de Azure Storage en una aplicación de iOS.

Para saber más de Blob Storage, consulte Introducción a Azure Blob Storage.

Creación de una cuenta de Azure Storage

La forma más fácil de crear la primera cuenta de Azure Storage es a través de Azure Portal. Para obtener más información, consulte Crear una cuenta de almacenamiento.

Puede crear también una cuenta de Azure Storage mediante Azure PowerShell, la CLI de Azure o el proveedor de recursos de Azure Storage para .NET.

Si no quiere crear una cuenta de almacenamiento en Azure en este momento, también puede utilizar el emulador de almacenamiento Azurite para ejecutar y probar el código en un entorno local. Para más información, consulte Uso del emulador de Azurite para desarrollo y pruebas locales de Azure Storage.

Importación de la biblioteca de iOS de Azure Storage en una aplicación

Puede importar la biblioteca de iOS de Azure Storage en la aplicación mediante el CocoaPod de Azure Storage o importando el archivo de marco . CocoaPod es la manera recomendada ya que facilita la integración de la biblioteca; sin embargo, la importación desde el archivo de plataforma es un método menos intrusivo para su proyecto existente.

Para usar esta biblioteca, necesita lo siguiente:

  • iOS 8+
  • Xcode 7+

CocoaPod

  1. Si aún no lo ha hecho, hecho instale CocoaPods en el equipo abriendo una ventana de terminal y ejecutando el siguiente comando.

    sudo gem install cocoapods
    
  2. Después, en el directorio del proyecto (el directorio que contiene el archivo .xcodeproj), cree un archivo llamado "Podfile" (sin extensión de archivo). Agregue lo siguiente a Podfile y guarde.

    platform :ios, '8.0'
    
    target 'TargetName' do
      pod 'AZSClient'
    end
    
  3. En la ventana terminal, vaya al directorio del proyecto y ejecute el siguiente comando.

    pod install
    
  4. Si el archivo .xcodeproj está abierto en Xcode, ciérrelo. En el directorio del proyecto, abra el archivo de proyecto recién creado que tendrá la extensión .xcworkspace. Este es el archivo en el que trabajará a partir de ahora.

marco

La otra forma de usar la biblioteca es generar la plataforma manualmente:

  1. En primer lugar, descargue o clone el repositorio azure-storage-ios.
  2. Vaya a azure-storage-ios ->Lib ->Biblioteca cliente de Azure Storage y abra AZSClient.xcodeproj en Xcode.
  3. En la parte superior izquierda de Xcode, cambie el esquema activo de "Azure Storage Client Library" (Biblioteca de cliente del Almacenamiento de Azure) a "Framework" (Marco).
  4. Compile el proyecto. Se crea un archivo AZSClient.framework en el escritorio.

Después puede importar el archivo de marco en la aplicación realizando el siguiente procedimiento:

  1. Cree un proyecto nuevo o abra un proyecto existente en Xcode.
  2. Arrastre y coloque AZSClient.framework en su navegador de proyecto de Xcode.
  3. Seleccione Copy items if needed (Copiar elementos si es necesario) y haga clic en Finish (Finalizar).
  4. Haga clic en el proyecto en el panel de navegación izquierdo y haga clic en la pestaña General de la parte superior del editor de proyectos.
  5. En la sección Linked Frameworks and Libraries (Bibliotecas y marcos vinculados) sección, haga clic en el botón Agregar (+).
  6. En la lista de bibliotecas ya proporcionada, busque libxml2.2.tbd y agréguelo al proyecto.

Importación de la biblioteca

// Include the following import statement to use blob APIs.
#import <AZSClient/AZSClient.h>

Si usa Swift, deberá crear un encabezado puente e importar <AZSClient/AZSClient.h> allí:

  1. Cree un archivo de encabezado Bridging-Header.h y agregue la instrucción "import" anterior.
  2. Vaya a la pestaña Configuración de compilación y busque Objective-C Bridging Header.
  3. Haga doble clic en el campo de Objective-C Bridging Header y agregue la ruta de acceso al archivo de encabezado: ProjectName/Bridging-Header.h
  4. Compile el proyecto (⌘+B) para comprobar que Xcode selecciona el encabezado puente.
  5. Comience a usar la biblioteca directamente en cualquier archivo Swift, no es necesario para las instrucciones "import".

Configuración de la aplicación para obtener acceso a Azure Storage

Hay dos maneras para autenticar una aplicación para tener acceso a los servicios de almacenamiento:

  • Clave compartida: la clave compartida solo se usa para realizar pruebas
  • Firma de acceso compartido (SAS): use SAS para las aplicaciones de producción

Clave compartida

La autenticación de clave compartida significa que la aplicación usará el nombre y la clave de la cuenta para tener acceso a los servicios de almacenamiento. Con el fin de mostrar rápidamente cómo usar esta biblioteca, emplearemos la autenticación de clave compartida en esta introducción.

Advertencia

Use la autenticación de clave compartida solamente para las pruebas. El nombre de cuenta y la clave de cuenta, que ofrecen acceso total de lectura y escritura a la cuenta de almacenamiento asociada, se distribuirán a todas las personas que descarguen la aplicación. Esta práctica no se recomienda, ya que se corre el riesgo de que los clientes en los que no se confía pongan la clave en peligro.

Si se usa la autenticación de clave compartida, se creará una cadena de conexión. La cadena de conexión consta de:

  • Protocolo DefaultEndpointsProtocol : puede elegir si usar HTTP o HTTPS. De todos modos, se recomienda encarecidamente el uso de HTTPS.
  • Nombre de cuenta : es el nombre de la cuenta de almacenamiento.
  • Clave de cuenta: en Azure Portal, navegue a la cuenta de almacenamiento y haga clic en el icono Claves para buscar esta información.
  • (Opcional) EndpointSuffix: se usa para servicios de almacenamiento en regiones con distintos sufijos de punto de conexión, como Azure China o Azure Governance.

Este es un ejemplo de cadena de conexión que usa la autenticación de clave compartida.

"DefaultEndpointsProtocol=https;AccountName=your_account_name_here;AccountKey=your_account_key_here"

Firmas de acceso compartido (SAS)

Para una aplicación móvil, el método recomendado para la autenticación de una solicitud por un cliente en el servicio Azure Storage es el uso de una firma de acceso compartido (SAS). SAS permite conceder a los clientes acceso a un recurso durante un período especificado, con un conjunto de permisos especificado. Como propietario de cuenta de almacenamiento, será preciso que genere una SAS para que la consuman los clientes móviles. Para generar la SAS, puede escribir un servicio independiente que genere la SAS que se va a distribuir a los clientes. Para la realización de pruebas puede usar el Explorador de Microsoft Azure Storage o Azure Portal para generar una SAS. Al crear la SAS, se puede especificar el intervalo de tiempo durante el que la SAS es válida y los permisos la SAS concede al cliente.

El siguiente ejemplo muestra cómo usar el Explorador de Microsoft Azure Storage para generar una SAS.

  1. Si no lo ha hecho ya, instale el Explorador de Microsoft Azure Storage

  2. Conéctese a su suscripción.

  3. Haga clic en la cuenta de almacenamiento y haga clic en la pestaña "Acciones" en la parte inferior izquierda. Haga clic en "Get Shared Access Signature" (Obtener firma de acceso compartido) para generar una "cadena de conexión" para la SAS.

  4. Este es un ejemplo de una cadena de conexión de SAS que concede permisos de lectura y escritura en el nivel de servicio, contenedor y objeto para Blob service de la cuenta de Storage.

    "SharedAccessSignature=sv=2015-04-05&ss=b&srt=sco&sp=rw&se=2016-07-21T18%3A00%3A00Z&sig=3ABdLOJZosCp0o491T%2BqZGKIhafF1nlM3MzESDDD3Gg%3D;BlobEndpoint=https://youraccount.blob.core.windows.net"

Como puede ver, cuando usa una SAS, no expone su clave de cuenta en la aplicación. Para obtener más información sobre SAS y los procedimientos de uso recomendados, consulte Firmas de acceso compartido: Descripción del modelo SAS.

Operaciones asincrónicas

Nota:

Todos los métodos que realizan una solicitud en el servicio son operaciones asincrónicas. En los ejemplos de código, verá que estos métodos tienen un controlador de finalización. El código de dentro del controlador de finalización se ejecutará después de que se haya completado la solicitud. El código posterior al controlador de finalización se ejecutará mientras se realiza la solicitud.

Crear un contenedor

Todos los blobs de Azure Storage deben residir en un contenedor. En el siguiente ejemplo, se muestra cómo crear un contenedor denominado newcontaineren su cuenta de almacenamiento (siempre y cuando no exista ya). Al elegir el nombre del contenedor, tenga en cuenta las reglas de nomenclatura mencionadas anteriormente.

-(void)createContainer{
    NSError *accountCreationError;

    // Create a storage account object from a connection string.
    AZSCloudStorageAccount *account = [AZSCloudStorageAccount accountFromConnectionString:@"DefaultEndpointsProtocol=https;AccountName=your_account_name_here;AccountKey=your_account_key_here" error:&accountCreationError];

    if(accountCreationError){
        NSLog(@"Error in creating account.");
    }

    // Create a blob service client object.
    AZSCloudBlobClient *blobClient = [account getBlobClient];

    // Create a local container object.
    AZSCloudBlobContainer *blobContainer = [blobClient containerReferenceFromName:@"newcontainer"];

    // Create container in your Storage account if the container doesn't already exist
    [blobContainer createContainerIfNotExistsWithCompletionHandler:^(NSError *error, BOOL exists) {
        if (error){
            NSLog(@"Error in creating container.");
        }
    }];
}

Para confirmar que esto funciona, examine el Explorador de Microsoft Azure Storage y compruebe que newcontainer está en la lista de contenedores de su cuenta de Storage.

Establecimiento de los permisos del contenedor

De manera predeterminada, los permisos de un contenedor se configuran para el acceso Privado . Sin embargo, los contenedores proporcionan varias opciones diferentes para acceder a ellos:

  • Privada: el propietario de la cuenta es el único que puede leer los datos del contenedor y de los blobs.
  • Blob: Los datos de blob dentro de este contenedor pueden leerse a través de una solicitud anónima, pero los datos del contenedor no están disponibles. Los clientes no pueden enumerar los blobs incluidos en el contenedor mediante una solicitud anónima.
  • Contenedor: los datos del contenedor y de los blobs se pueden leer mediante una solicitud anónima. Los clientes pueden enumerar los blobs del contenedor a través de una solicitud anónima, pero no pueden enumerar los contenedores que están en la cuenta de almacenamiento.

En el ejemplo siguiente se muestra cómo crear un contenedor con permiso de acceso de Contenedor que permita el acceso público, de solo lectura, a todos los usuarios de Internet:

-(void)createContainerWithPublicAccess{
    NSError *accountCreationError;

    // Create a storage account object from a connection string.
    AZSCloudStorageAccount *account = [AZSCloudStorageAccount accountFromConnectionString:@"DefaultEndpointsProtocol=https;AccountName=your_account_name_here;AccountKey=your_account_key_here" error:&accountCreationError];

    if(accountCreationError){
        NSLog(@"Error in creating account.");
    }

    // Create a blob service client object.
    AZSCloudBlobClient *blobClient = [account getBlobClient];

    // Create a local container object.
    AZSCloudBlobContainer *blobContainer = [blobClient containerReferenceFromName:@"containerpublic"];

    // Create container in your Storage account if the container doesn't already exist
    [blobContainer createContainerIfNotExistsWithAccessType:AZSContainerPublicAccessTypeContainer requestOptions:nil operationContext:nil completionHandler:^(NSError *error, BOOL exists){
        if (error){
            NSLog(@"Error in creating container.");
        }
    }];
}

Cargar un blob en un contenedor

Como se mencionó en la sección sobre conceptos de Blob Service, Blob Storage ofrece tres tipos de blob: blob en bloques, blob en anexos y blob en páginas. La biblioteca de iOS de Azure Storage admite los tres tipos de blobs. En la mayoría de los casos, se recomienda usar blobs en bloques.

En el ejemplo siguiente se muestra cómo cargar un blob en bloques de un NSString. Si ya existe un blob con el mismo nombre en el contenedor, se sobrescribirá el contenido de dicho blob.

-(void)uploadBlobToContainer{
    NSError *accountCreationError;

    // Create a storage account object from a connection string.
    AZSCloudStorageAccount *account = [AZSCloudStorageAccount accountFromConnectionString:@"DefaultEndpointsProtocol=https;AccountName=your_account_name_here;AccountKey=your_account_key_here" error:&accountCreationError];

    if(accountCreationError){
        NSLog(@"Error in creating account.");
    }

    // Create a blob service client object.
    AZSCloudBlobClient *blobClient = [account getBlobClient];

    // Create a local container object.
    AZSCloudBlobContainer *blobContainer = [blobClient containerReferenceFromName:@"containerpublic"];

    [blobContainer createContainerIfNotExistsWithAccessType:AZSContainerPublicAccessTypeContainer requestOptions:nil operationContext:nil completionHandler:^(NSError *error, BOOL exists)
        {
            if (error){
                NSLog(@"Error in creating container.");
            }
            else{
                // Create a local blob object
                AZSCloudBlockBlob *blockBlob = [blobContainer blockBlobReferenceFromName:@"sampleblob"];

                // Upload blob to Storage
                [blockBlob uploadFromText:@"This text will be uploaded to Blob Storage." completionHandler:^(NSError *error) {
                    if (error){
                        NSLog(@"Error in creating blob.");
                    }
                }];
            }
        }];
}

Para confirmar que esto funciona, examine el Explorador de Microsoft Azure Storage y compruebe que el contenedor, containerpublic, contiene el blob sampleblob. En este ejemplo, se usa un contenedor público, por lo que para comprobar que esta aplicación ha funcionado puede ir al URI de los blobs:

https://nameofyourstorageaccount.blob.core.windows.net/containerpublic/sampleblob

Además de cargar un blob en bloques desde NSString, hay métodos similares para NSData, NSInputStream o un archivo local.

Enumerar los blobs de un contenedor

En el ejemplo siguiente se muestra cómo enumerar todos los blobs en un contenedor. Al realizar esta operación, tenga en cuenta los siguientes parámetros:

  • continuationToken : el token de continuación representa el lugar en el que debe iniciarse la operación de lista. Si no se proporciona ningún token, los blobs se enumerarán desde el principio. Se puede enumerar cualquier número de blobs, desde cero hasta el máximo configurado. Aunque este método devuelve cero como resultado, si results.continuationToken no es nulo, puede haber más blobs en el servicio que no se hayan enumerado.
  • prefix : puede especificar el prefijo que se va a usar para la lista de blobs. Solo se enumerarán los blobs que comiencen por dicho prefijo.
  • useFlatBlobListing: como se mencionó en la sección Asignación de nombres y referencia a contenedores y blobs, aunque Blob service es un esquema plano de almacenamiento, puede crear una jerarquía virtual asignando a los blobs el nombre de la información de la ruta de acceso. Sin embargo, actualmente no se admiten listas que no sean planas. Esta característica estará disponible próximamente. Por el momento, este valor debe ser .
  • blobListingDetails : puede especificar qué elementos desea incluir al enumerar los blobs
    • AZSBlobListingDetailsNone: se enumeran solo los blobs confirmados y no se devuelven los metadatos de los blobs.
    • AZSBlobListingDetailsSnapshots: se enumeran los blobs confirmados y las instantáneas de los blobs.
    • AZSBlobListingDetailsMetadata: se recuperan los metadatos de los blobs que se devuelven en la lista.
    • AZSBlobListingDetailsUncommittedBlobs: se enumeran los blobs confirmados y sin confirmar.
    • AZSBlobListingDetailsCopy: se incluyen propiedades de copia en la lista.
    • AZSBlobListingDetailsAll: se enumeran todos los blobs confirmados, blobs sin confirmar e instantáneas disponibles y se devuelven todos los metadatos y estados de copia de dichos blobs.
  • maxResults : el número máximo de resultados que se devuelven para esta operación. Utilice -1 para no establecer un límite.
  • completionHandler : el bloque de código que se ejecutará con los resultados de la operación de lista.

En este ejemplo, se usa un método auxiliar para llamada de forma recursiva el método de blobs de lista cada vez que se devuelve un token de continuación.

-(void)listBlobsInContainer{
    NSError *accountCreationError;

    // Create a storage account object from a connection string.
    AZSCloudStorageAccount *account = [AZSCloudStorageAccount accountFromConnectionString:@"DefaultEndpointsProtocol=https;AccountName=your_account_name_here;AccountKey=your_account_key_here" error:&accountCreationError];

    if(accountCreationError){
        NSLog(@"Error in creating account.");
    }

    // Create a blob service client object.
    AZSCloudBlobClient *blobClient = [account getBlobClient];

    // Create a local container object.
    AZSCloudBlobContainer *blobContainer = [blobClient containerReferenceFromName:@"containerpublic"];

    //List all blobs in container
    [self listBlobsInContainerHelper:blobContainer continuationToken:nil prefix:nil blobListingDetails:AZSBlobListingDetailsAll maxResults:-1 completionHandler:^(NSError *error) {
        if (error != nil){
            NSLog(@"Error in creating container.");
        }
    }];
}

//List blobs helper method
-(void)listBlobsInContainerHelper:(AZSCloudBlobContainer *)container continuationToken:(AZSContinuationToken *)continuationToken prefix:(NSString *)prefix blobListingDetails:(AZSBlobListingDetails)blobListingDetails maxResults:(NSUInteger)maxResults completionHandler:(void (^)(NSError *))completionHandler
{
    [container listBlobsSegmentedWithContinuationToken:continuationToken prefix:prefix useFlatBlobListing:YES blobListingDetails:blobListingDetails maxResults:maxResults completionHandler:^(NSError *error, AZSBlobResultSegment *results) {
        if (error)
        {
            completionHandler(error);
        }
        else
        {
            for (int i = 0; i < results.blobs.count; i++) {
                NSLog(@"%@",[(AZSCloudBlockBlob *)results.blobs[i] blobName]);
            }
            if (results.continuationToken)
            {
                [self listBlobsInContainerHelper:container continuationToken:results.continuationToken prefix:prefix blobListingDetails:blobListingDetails maxResults:maxResults completionHandler:completionHandler];
            }
            else
            {
                completionHandler(nil);
            }
        }
    }];
}

Descarga de un blob

En el ejemplo siguiente se muestra cómo descargar un blob en un objeto NSString.

-(void)downloadBlobToString{
    NSError *accountCreationError;

    // Create a storage account object from a connection string.
    AZSCloudStorageAccount *account = [AZSCloudStorageAccount accountFromConnectionString:@"DefaultEndpointsProtocol=https;AccountName=your_account_name_here;AccountKey=your_account_key_here" error:&accountCreationError];

    if(accountCreationError){
        NSLog(@"Error in creating account.");
    }

    // Create a blob service client object.
    AZSCloudBlobClient *blobClient = [account getBlobClient];

    // Create a local container object.
    AZSCloudBlobContainer *blobContainer = [blobClient containerReferenceFromName:@"containerpublic"];

    // Create a local blob object
    AZSCloudBlockBlob *blockBlob = [blobContainer blockBlobReferenceFromName:@"sampleblob"];

    // Download blob
    [blockBlob downloadToTextWithCompletionHandler:^(NSError *error, NSString *text) {
        if (error) {
            NSLog(@"Error in downloading blob");
        }
        else{
            NSLog(@"%@",text);
        }
    }];
}

Eliminar un blob

En el ejemplo siguiente se muestra cómo eliminar un blob.

-(void)deleteBlob{
    NSError *accountCreationError;

    // Create a storage account object from a connection string.
    AZSCloudStorageAccount *account = [AZSCloudStorageAccount accountFromConnectionString:@"DefaultEndpointsProtocol=https;AccountName=your_account_name_here;AccountKey=your_account_key_here" error:&accountCreationError];

    if(accountCreationError){
        NSLog(@"Error in creating account.");
    }

    // Create a blob service client object.
    AZSCloudBlobClient *blobClient = [account getBlobClient];

    // Create a local container object.
    AZSCloudBlobContainer *blobContainer = [blobClient containerReferenceFromName:@"containerpublic"];

    // Create a local blob object
    AZSCloudBlockBlob *blockBlob = [blobContainer blockBlobReferenceFromName:@"sampleblob1"];

    // Delete blob
    [blockBlob deleteWithCompletionHandler:^(NSError *error) {
        if (error) {
            NSLog(@"Error in deleting blob.");
        }
    }];
}

un contenedor de blobs

En el ejemplo siguiente se muestra cómo eliminar un contenedor.

-(void)deleteContainer{
    NSError *accountCreationError;

    // Create a storage account object from a connection string.
    AZSCloudStorageAccount *account = [AZSCloudStorageAccount accountFromConnectionString:@"DefaultEndpointsProtocol=https;AccountName=your_account_name_here;AccountKey=your_account_key_here" error:&accountCreationError];

    if(accountCreationError){
        NSLog(@"Error in creating account.");
    }

    // Create a blob service client object.
    AZSCloudBlobClient *blobClient = [account getBlobClient];

    // Create a local container object.
    AZSCloudBlobContainer *blobContainer = [blobClient containerReferenceFromName:@"containerpublic"];

    // Delete container
    [blobContainer deleteContainerIfExistsWithCompletionHandler:^(NSError *error, BOOL success) {
        if(error){
            NSLog(@"Error in deleting container");
        }
    }];
}

Pasos siguientes

Ahora que ha aprendido cómo utilizar Blob Storage de iOS, siga estos vínculos para más información sobre la biblioteca de iOS y el servicio de almacenamiento.

Si tiene alguna pregunta sobre esta biblioteca, puede publicarla en la Página de preguntas y respuestas o en Stack Overflow. Si quiere sugerir características nuevas para Azure Storage, publíquelas en la página de comentarios sobre Azure Storage.