Cambios en StoreKit en iOS 6

iOS 6 introdujo dos cambios en la API del Kit de la Tienda: la capacidad de mostrar productos de iTunes (y App Store/iBookstore) desde dentro de la aplicación y una nueva opción de compra desde la aplicación donde Apple hospedará los archivos descargables. En este documento se explica cómo implementar esas características con Xamarin.iOS.

Los cambios principales en Store Kit en iOS6 son estas dos características nuevas:

  • contenido en la aplicación Mostrar y comprar – los usuarios pueden comprar y descargar aplicaciones, música, libros y otro contenido de iTunes sin salir de la aplicación. También puede vincular a sus propias aplicaciones para promover la compra o simplemente fomentar opiniones y clasificaciones.
  • contenido hospedado de compra desde la aplicación – Apple almacenará y entregará el contenido asociado a los productos de compra desde la aplicación, lo que elimina la necesidad de que un servidor independiente hospede los archivos, admite automáticamente la descarga en segundo plano y le permite escribir menos código.

Consulta las guías de compras desde la aplicación para obtener una cobertura detallada de las API de StoreKit.

Requisitos

Las características del Kit de la Tienda que se describen en este documento requieren iOS 6 y Xcode 4.5, junto con Xamarin.iOS 6.0.

Presentación y compra de contenido en la aplicación

La nueva característica de compra desde la aplicación en iOS permite a los usuarios ver información del producto y comprar o descargar el producto desde dentro de la aplicación. Las aplicaciones anteriores tendrían que desencadenar iTunes, app Store o iBookstore, lo que daría lugar a que el usuario dejara la aplicación original. Esta nueva característica devuelve automáticamente el usuario a la aplicación cuando haya terminado.

Automatically returning to an app after purchase

Entre los ejemplos de cómo se podría usar, se incluyen:

  • Animar a los usuarios a valorar la aplicación – Puedes abrir la página de App Store para que el usuario pueda valorar y revisar la aplicación sin salir de ella.
  • aplicaciones de promoción cruzada – Permitir al usuario ver otras aplicaciones que publique, con la capacidad de comprar o descargar inmediatamente.
  • Ayudar a los usuarios a encontrar y descargar contenido – Ayudar a los usuarios a comprar contenido que la aplicación encuentra, administra o agrega (por ejemplo, una aplicación relacionada con la música podría proporcionar una lista de reproducción de canciones y permitir que cada canción se compre desde dentro de la aplicación).

Una vez que se ha mostrado el SKStoreProductViewController, el usuario puede interactuar con la información del producto como si estuvieran en iTunes, app Store o iBookstore. El usuario puede:

  • Ver capturas de pantalla (para aplicaciones),
  • Muestra de canciones o vídeos (para música, programas de TELEVISIÓN y películas),
  • Revisiones de lectura (y escritura),
  • Comprar y descargar, lo que sucede completamente dentro del controlador de vista y el Kit de la Tienda.

Algunas opciones dentro del SKStoreProductViewController seguirán obligando al usuario a abandonar la aplicación y abrir la aplicación de la tienda pertinente, como hacer clic en productos relacionados o un vínculo de soporte técnico de la aplicación’.

SKStoreProductViewController

La API para mostrar un producto dentro de cualquier aplicación es sencillo: solo requiere que cree y muestre un SKStoreProductViewController. Siga estos pasos para crear y mostrar un producto:

  1. Cree un objeto StoreProductParameters para pasar parámetros al controlador de vista, incluido el productId en el constructor.
  2. Crear una instancia de SKProductViewController. Asígnelo a un campo de nivel de clase.
  3. Asigne un controlador al evento Finished del controlador’de vista, que debe descartar el controlador de vista. Se llama a este evento cuando el usuario presiona la cancelación; o finaliza una transacción dentro del controlador de vista.
  4. Llame al método LoadProduct pasando el StoreProductParameters y un controlador de finalización. El controlador de finalización debe comprobar que la solicitud del producto se realizó correctamente y, si es así, presente el SKProductViewController modally. Se debe agregar el control de errores adecuado en caso de que no se pueda recuperar el producto.

Ejemplo

El proyecto ProductView del StoreKit código de ejemplo para este artículo implementa un método Buy que acepta cualquier id. de Apple del producto y muestra el SKStoreProductViewController. El código siguiente muestra la información del producto para cualquier id. de Apple determinado:

void Buy (int productId)
{
    var spp = new StoreProductParameters(productId);
    var productViewController = new SKStoreProductViewController ();
    // must set the Finished handler before displaying the view controller
    productViewController.Finished += (sender, err) => {
        // Apple's docs says to use this method to close the view controller
        this.DismissModalViewControllerAnimated (true);
    };
    productViewController.LoadProduct (spp, (ok, err) => { // ASYNC !!!
        if (ok) {
            PresentModalViewController (productViewController, true);
        } else {
            Console.WriteLine (" failed ");
            if (err != null)
                Console.WriteLine (" with error " + err);
        }
    });
}

La aplicación tiene un aspecto similar a la siguiente captura de pantalla cuando se ejecuta – la descarga o la compra se produce completamente dentro de la SKStoreProductViewController:

The app looks like this when running

Compatibilidad con sistemas operativos más antiguos

La aplicación de ejemplo incluye código que muestra cómo abrir app Store, iTunes o iBookstore en versiones anteriores de iOS. Use el OpenUrl método para abrir una dirección URL de itunes.com diseñada correctamente.

Puede implementar una comprobación de versión para determinar qué código se va a ejecutar, como se muestra aquí:

if (UIDevice.CurrentDevice.CheckSystemVersion (6,0)) {
    // do iOS6+ stuff, using SKStoreProductViewController as shown above
} else {
    // don't do stuff requiring iOS 6.0, use the old syntax
    // (which will take the user out of your app)
    var nsurl = new NSUrl("http://itunes.apple.com/us/app/angry-birds/id343200656?mt=8");
    UIApplication.SharedApplication.OpenUrl (nsurl);
}

Errores

El siguiente error se producirá si el identificador de Apple que usa no es válido, lo que puede resultar confuso, ya que implica un problema de red o autenticación de algún tipo.

Error Domain=SKErrorDomain Code=5 "Cannot connect to iTunes Store"

Leer la documentación de Objective-C

Los desarrolladores que leen acerca de Store Kit en el Portal para desarrolladores de Apple’verán un protocolo – SKStoreProductViewControllerDelegate – analizado en relación con esta nueva característica. El protocolo delegado solo tiene un método – productViewControllerDidFinish – que se ha expuesto como evento de Finished en el SKStoreProductViewController en Xamarin.iOS.

Determinación de identificadores de Apple

El id. de Apple requerido por el SKStoreProductViewController es un número (no confundirse con identificadores de agrupación como “com.xamarin.mwc2012”). Hay varias maneras diferentes de averiguar el id. de Apple para los productos que desea mostrar, que se enumeran a continuación:

iTunesConnect

Para las aplicaciones que publique, es fácil encontrar la id. de Apple en iTunes Connect:

Finding the Apple ID in iTunes Connect

Buscar API

Apple proporciona una API de búsqueda dinámica para consultar todos los productos de app Store, iTunes y iBookstore. Puede encontrar información sobre cómo acceder a la API de búsqueda en los recursos de filiales de Apple, aunque la API se expone a cualquier persona (no solo a filiales registradas). El JSON resultante se puede analizar para detectar el trackId que es el identificador de Apple que se va a usar con SKStoreProductViewController.

Los resultados también incluirán otros metadatos, como la información de visualización y las direcciones URL de ilustraciones que se pueden usar para representar el producto en la aplicación.

Estos son algunos ejemplos:

Fuente de partners empresariales

Apple proporciona a los asociados aprobados un volcado de datos completo de todos sus productos, en forma de archivos planos listos para la base de datos descargables. Si cumple los requisitos para acceder al Enterprise Partner Feed, el id. de Apple para cualquier producto se puede encontrar en ese conjunto de datos.

Muchos usuarios de Enterprise Partner Feed son miembros del programa de afiliados que permite obtener comisiones en las ventas de productos. SKStoreProductViewController no admite identificadores de afiliados (en el momento de escribir).

El id. de Apple de un producto se puede deducir de su vínculo URL de iTunes Preview. En cualquier vínculo de producto de iTunes (para aplicaciones, música o libros) busque la parte de la dirección URL a partir de id y use el número siguiente.

Por ejemplo, el vínculo directo a iBooks es

http://itunes.apple.com/us/app/ibooks/id364709193?mt=8

y el id. de Apple es 364709193. Del mismo modo para la aplicación de MWC2012, el vínculo directo es

http://itunes.apple.com/us/app/mwc-2012-unofficial/id496963922?mt=8

y el id. de Apple es 496963922.

Contenido hospedado de compra en la aplicación

Si las compras desde la aplicación constan de contenido descargable (como libros u otros medios, arte y configuración de nivel de juego u otros archivos grandes), estos archivos solían hospedarse en el servidor web y las aplicaciones tenían que incorporar código para descargarlos de forma segura después de la compra. A partir de iOS 6, Apple hospedará los archivos en sus servidores, eliminando la necesidad de un servidor independiente. La característica solo está disponible para productos no consumibles (no consumibles ni suscripciones). Entre las ventajas del uso del servicio de hospedaje de Apple se incluyen:

  • Ahorre costos de hospedaje y ancho de banda.
  • Probablemente sea más escalable que cualquier host de servidor que esté usando actualmente.
  • Menos código que escribir, ya que no tiene que compilar ningún procesamiento del lado servidor.
  • La descarga en segundo plano se implementa automáticamente.

Nota: No se admite la prueba de contenido de compra hospedado en la aplicación en el simulador de iOS, por lo que debe probar con un dispositivo real.

Conceptos básicos de contenido hospedado

Antes de iOS 6, había dos maneras de proporcionar un producto (descrito con más detalle en documentación de Xamarin’s In-App Purchase):

  • Productos integrados – características que se desbloquean ‘’ mediante la compra, pero que están integradas en la aplicación (ya sea como código o recursos incrustados). Algunos ejemplos de productos integrados incluyen filtros fotográficos desbloqueados o power-ups en el juego.
  • Productos entregados por el servidor – Después de la compra, la aplicación debe descargar contenido de un servidor que opera. Este contenido se descarga durante la compra, se almacena en el dispositivo y, a continuación, se representa como parte del suministro del producto. Algunos ejemplos incluyen libros, problemas de revistas o niveles de juego que constan de archivos de arte de fondo y configuración.

En iOS 6 Apple ofrece una variación de los productos entregados por el servidor: hospedarán los archivos de contenido en sus servidores. Esto facilita mucho la compilación de productos entregados por el servidor, ya que no es necesario para operar un servidor independiente, y Store Kit proporciona funcionalidad de descarga en segundo plano que antes tenía que escribir usted mismo. Para aprovechar el hospedaje de Apple, habilite el hospedaje de contenido para nuevos productos de compra desde la aplicación y modifique el código del Kit de la Tienda para aprovecharlo. Los archivos de contenido del producto se compilan con Xcode y se cargan en los servidores de Apple para su revisión y lanzamiento.

The build and deliver process

El uso de App Store para proporcionar de compra desde la aplicación con contenido hospedado requiere la siguiente configuración y configuración:

  • iTunes Connect – Usted debe haber proporcionado su información bancaria e fiscal a Apple para que puedan remitir fondos recopilados en su nombre. A continuación, puede configurar productos para vender y configurar cuentas de usuario de espacio aislado para probar la compra. También debe configurar contenido hospedado para aquellos productos no consumibles que desee hospedar con Apple.
  • portal de aprovisionamiento de iOS – Creación de un identificador de lote y habilitación del acceso a App Store para la aplicación, como lo haría con cualquier aplicación que admita la compra desde la aplicación.
  • Kit de la Tienda – Agregar código a la aplicación para mostrar productos, comprar productos y restaurar transacciones. En iOS 6 Store Kit también administrará la descarga del contenido del producto, en segundo plano, con actualizaciones de progreso.
  • código personalizado – Para realizar un seguimiento de las compras realizadas por los clientes y proporcionar los productos o servicios que’han comprado. Use nuevas clases del Kit de la Tienda iOS 6 como SKDownload para recuperar el contenido hospedado por Apple.

En las secciones siguientes se explica cómo implementar contenido hospedado, desde la creación y carga del paquete hasta la administración del proceso de compra y descarga mediante el código de ejemplo de este artículo.

Código de ejemplo

El proyecto de ejemplo HostedNonConsumables (en StoreKitiOS6.zip) usa contenido hospedado. La aplicación ofrece dos “capítulos” de libros en venta, el contenido para el que se hospeda en los servidores de Apple’. El contenido consta de un archivo de texto y una imagen, aunque se podría usar contenido mucho más complejo en una aplicación real.

La aplicación tiene este aspecto antes, durante y después de una compra:

The app looks like this before, during and after a purchase

El archivo de texto y la imagen se descargan y copian en el directorio Documents de la aplicación. Para obtener más información sobre los distintos directorios disponibles para el almacenamiento de aplicaciones, consulte la documentación del sistema de archivos .

iTunes Connect

Al crear nuevos productos que usarán el hospedaje de contenido de Apple’, asegúrese de seleccionar la tipo de producto no consumible. Otros tipos de productos no admiten el hospedaje de contenido. Además, no debe habilitar el hospedaje de contenido para productos existentes que vende; active solo el hospedaje de contenido para nuevos productos.

Select the Non-Consumable product type

Escriba un identificador de producto. Este identificador será necesario más adelante cuando cree el contenido de este producto.

Enter a Product ID

El hospedaje de contenido se establece en la sección Detalles. Antes de que la compra desde la aplicación esté activa, desactive la casilla Contenido de host con Apple si desea cancelar (incluso si ha cargado algún contenido de prueba). Sin embargo, no se puede quitar el hospedaje de contenido después de que la compra desde la aplicación se haya vuelto activa.

Hosting content with Apple

Una vez que haya activado el contenido de hospedaje, el producto escribirá Estado de espera de carga y mostrará este mensaje:

The product will enter Waiting for Upload status and show this message

El paquete de contenido debe crearse con Xcode y cargarse mediante la herramienta Archive. Las instrucciones para crear paquetes de contenido se proporcionan en la sección siguiente Crear . Archivos PKG.

Crear. Archivos PKG

Los archivos de contenido que cargue en Apple deben cumplir las restricciones siguientes:

  • No se pueden superar los 2 GB de tamaño.
  • No se puede contener código ejecutable (o vínculos simbólicos que apuntan fuera del contenido).
  • Debe tener el formato correcto (incluido un archivo .plist ) y tener una extensión de archivo .pkg. Esto se realizará automáticamente si sigue estas instrucciones mediante Xcode.

Puede agregar muchos archivos diferentes y tipos de archivos, siempre y cuando cumplan estas restricciones. El contenido se comprime antes de la entrega a la aplicación y descomprimido por el Kit de la Tienda antes de que el código acceda a ella.

Después de cargar un paquete de contenido, se puede reemplazar por contenido más reciente. El nuevo contenido debe cargarse y enviarse para su revisión o aprobación a través del proceso normal. Incremente el campo ContentVersion en los paquetes de contenido actualizados para indicar que es más reciente.

Proyectos de contenido de compra desde la aplicación de Xcode

La creación de paquetes de contenido para productos de compra desde la aplicación requiere actualmente Xcode. No se requiere CODIFICACIÓN OBJECTIVE-C; Xcode tiene un nuevo tipo de proyecto para estos paquetes que solo contiene los archivos y una plist.

Nuestra aplicación de ejemplo tiene capítulos de libros para la venta – cada paquete de contenido de capítulos contendrá:

  • un archivo de texto y
  • una imagen que representa el capítulo.

Para empezar, seleccione Archivo > Nuevo proyecto en el menú y elija Contenido de compra desde la aplicación:

Choose In-App Purchase Content

Escriba el nombre de producto y identificador de empresa de modo que el identificador de agrupación coincida con el id. de productoque especificó en iTunes Connect para este producto.

Enter the Name and Identifier

Ahora tendrá un proyecto contenido de compra desde la aplicación en blanco. Puede hacer clic con el botón derecho y Agregar archivos… o arrastrarlos al Project Navigator. Asegúrese de que el ContentVersion sea correcto (debería empezar a la 1.0, pero si más adelante decide actualizar el contenido, recuerde incrementarlo).

En esta captura de pantalla se muestra Xcode con los archivos de contenido incluidos en el proyecto y las entradas de plist visibles en la ventana principal:

This screenshot shows Xcode with the content files included in the project and the plist entries visible in the main window

Una vez que haya agregado todos los archivos de contenido, puede guardar este proyecto y editarlo de nuevo más tarde o comenzar el proceso de carga.

Cargar. Archivos PKG

La manera más fácil de cargar paquetes de contenido es con la herramienta de archivo Xcode. Elija Archivo> del producto en el menú para comenzar:

Choose Archiven

A continuación, el paquete de contenido aparecerá en el archivo, como se muestra a continuación. El tipo de archivo y el icono muestran esta línea es una archivo de contenido de compra desde la aplicación. Haga clic en Validar… para comprobar si hay errores en el paquete de contenido sin realizar realmente la carga.

Validate the package

Inicie sesión con sus credenciales de iTunes Connect:

Login with your iTunes Connect credentials

Elija la aplicación correcta y la compra desde la aplicación para asociar este contenido a:

Choose the correct application and in-app purchase to associate this content with

Debería ver un mensaje similar a esta captura de pantalla:

An example no issues message

Ahora pase por un proceso similar, pero al hacer clic en Distribuir… realmente se cargará el contenido.

Distribute the app

Seleccione la primera opción para cargar el contenido:

Upload the content

Vuelva a iniciar sesión:

Login in

Elija la aplicación correcta y el registro de compra desde la aplicación para cargar el contenido en:

Choose the application and in-app purchase record

Espere mientras se cargan los archivos:

The content upload dialog

Una vez completada la carga, aparecerá un mensaje para avisarle de que el contenido se ha enviado a app Store.

An example successful upload message

Una vez hecho esto, cuando vuelvas a la página del producto en iTunes Connect, mostrará los detalles del paquete y estará en Estado listo para enviar. Cuando el producto está en este estado, puede empezar a probar en el entorno de espacio aislado. No es necesario ‘enviar’ el producto para realizar pruebas en el espacio aislado.

iTunes Connect it will show the package details and be in Ready to Submit status

Puede tardar algún tiempo (por ejemplo, unos minutos) entre cargar el archivo y el estado de iTunes Connect que se está actualizando. Puede enviar el producto para su revisión por separado o enviarlo junto con un binario de aplicación. Solo después de que Apple haya aprobado oficialmente el contenido estará disponible en la App Store de producción para su compra en la aplicación.

Formato de archivo PKG

El uso de Xcode y la herramienta de archivo para crear y cargar un paquete de contenido hospedado significa que nunca se ve el contenido del propio paquete. Los archivos y directorios de los paquetes creados para la aplicación de ejemplo tienen un aspecto similar al siguiente, con el archivo plist en la raíz y los archivos de producto de un subdirectorio Contenido:

The plist file in the root and the product files in a Contents subdirectory

Tenga en cuenta la estructura de directorios del paquete (especialmente la ubicación de los archivos en el subdirectorio Contents) porque deberá comprender esta información para extraer los archivos del paquete en el dispositivo.

Actualización del contenido del paquete

Procedimiento para actualizar el contenido una vez aprobado:

  • Edite el proyecto Contenido de compra desde la aplicación en Xcode.
  • Aumente el número de versión.
  • Vuelva a cargar en iTunes Connect. Los compradores posteriores recibirán automáticamente la versión más reciente, pero los usuarios que ya tengan la versión anterior no recibirán ninguna notificación.
  • La aplicación es responsable de notificar a los usuarios y animarlas a recuperar una versión más reciente del contenido. La aplicación también debe compilar una función que descargue la nueva versión mediante la característica Restaurar del Kit de la Tienda.
  • Para determinar si existe una versión más reciente, puede crear una característica en la aplicación para capturar SKProducts (por ejemplo, el mismo proceso que se usa para recuperar los precios del producto) y comparar la propiedad ContentVersion.

Información general de compras

Antes de leer esta sección, revise la documentación de compra desde la aplicación existente .

La secuencia de eventos que se produce cuando se compra un producto con contenido hospedado y la descarga se ilustra en este diagrama:

The sequence of events that occurs when a product with hosted content is purchased and download

  1. Los nuevos productos se pueden crear en iTunes Connect con contenido hospedado habilitado. El contenido real se construye por separado en Xcode (como simplemente arrastrar archivos a una carpeta) y, a continuación, Archivado y cargado en iTunes (no se requiere codificación). A continuación, cada producto se envía para su aprobación, después de lo cual estará disponible para su compra. En el código de ejemplo, estos identificadores de producto están codificados de forma rígida, pero el hospedaje de contenido con Apple es más flexible si almacena la lista de productos disponible en un servidor remoto para que se pueda actualizar al enviar nuevos productos y contenido a iTunes Connect.
  2. Cuando el usuario compra un producto, se coloca una transacción en la cola de pago para su procesamiento.
  3. Store Kit reenvía la solicitud de compra a los servidores de iTunes para su procesamiento.
  4. La transacción se completa en los servidores de iTunes (por ejemplo, se cobra al cliente) y se devuelve un recibo a la aplicación, con información del producto adjunta, incluida si se puede descargar (y, si es así, el tamaño del archivo y otros metadatos).
  5. El código debe comprobar si el producto es descargable y, si es así, realizar una solicitud de descarga de contenido que también se coloca en la cola de pago. Store Kit envía esta solicitud a los servidores de iTunes.
  6. El servidor devuelve el archivo de contenido al Kit de almacenamiento, que proporciona una devolución de llamada para devolver el progreso de la descarga y el tiempo restante de las estimaciones del código.
  7. Una vez completado, recibirá una notificación y pasará una ubicación de archivo en la carpeta Caché.
  8. El código debe copiar los archivos y comprobarlos, guardar cualquier estado que necesite recordar que se ha comprado el producto. Aproveche esta oportunidad para establecer la marca de copia de seguridad correctamente en los nuevos archivos (sugerencia: si proceden de un servidor y nunca los edita el usuario, es probable que omita la copia de seguridad, ya que el usuario siempre puede recuperarlos de los servidores de Apple’en el futuro).
  9. Call FinishTransaction. Este paso es IMPORTANTE, ya que quita la transacción de la cola de pago. También es importante que no llame a FinishTransaction hasta QUE haya copiado el contenido del directorio Cache. Una vez que llame a FinishTransaction, es probable que los archivos almacenados en caché se purguen rápidamente.

Implementación de la compra de contenido hospedado

La siguiente información debe leerse junto con la documentación completa de compras desde la aplicación. La información de este documento se centra en las diferencias entre el contenido hospedado y la implementación anterior.

Clases

Se han agregado o modificado las siguientes clases para admitir el contenido hospedado en iOS 6:

  • SKDownload – Nueva clase que representa una descarga en curso. La API permite más de un producto, pero inicialmente solo se ha implementado uno.
  • SKProduct – Nuevas propiedades agregadas: Downloadable, ContentVersion, ContentLengths matriz.
  • SKPaymentTransaction – Nueva propiedad agregada: Downloads, que contiene una colección de objetos SKDownload si este producto tiene contenido hospedado disponible para descarga.
  • SKPaymentQueue – nuevo método agregado: StartDownloads. Llame a este método con SKDownload objetos para capturar su contenido hospedado. La descarga puede producirse en segundo plano.
  • SKPaymentTransactionObserver – nuevo método: UpdateDownloads. Store Kit llama a este método con información de progreso sobre las operaciones de descarga actuales.

Detalles de la nueva clase SKDownload:

  • Progreso – Un valor entre 0 y 1 que puede usar para mostrar un indicador de porcentaje completo al usuario. No use Progress == 1 para detectar si la descarga está completa, busque Estado == Finalizado.
  • TimeRemaining – Estimación del tiempo de descarga restante, en segundos. -1 significa que sigue calculando la estimación.
  • Estado – activo, en espera, finalizado, con error, en pausa, cancelado.
  • ContentURL – ubicación del archivo donde se puso el contenido en el disco, en el directorio Cache. SOLO se rellena una vez finalizada la descarga.
  • Error – Compruebe esta propiedad si el estado es Error.

Las interacciones entre las clases del código de ejemplo se muestran en este diagrama (el código específico de las compras de contenido hospedado se muestra en verde):

Hosted content purchases is shown in green in this diagram

El código de ejemplo donde se han usado estas clases se muestra en el resto de esta sección:

CustomPaymentObserver (SKPaymentTransactionObserver)

Cambie la invalidación del UpdatedTransactions existente para comprobar el contenido descargable y llame a StartDownloads si es necesario:

public override void UpdatedTransactions (SKPaymentQueue queue, SKPaymentTransaction[] transactions)
{
    foreach (SKPaymentTransaction transaction in transactions) {
        switch (transaction.TransactionState) {
        case SKPaymentTransactionState.Purchased:
            // UPDATED FOR iOS 6
            if (transaction.Downloads != null && transaction.Downloads.Length > 0) {
                // Purchase complete, and it has downloads... so download them!
                SKPaymentQueue.DefaultQueue.StartDownloads (transaction.Downloads);
                // CompleteTransaction() call has moved after downloads complete
            } else {
                // complete the transaction now
                theManager.CompleteTransaction(transaction);
            }
            break;
        case SKPaymentTransactionState.Failed:
            theManager.FailedTransaction(transaction);
            break;
        case SKPaymentTransactionState.Restored:
            // TODO: you must decide how to handle restored transactions.
            // Triggering all the downloads at once is not advisable.
            theManager.RestoreTransaction(transaction);
            break;
        default:
            break;
        }
    }
}

A continuación se muestra el nuevo método invalidado UpdatedDownloads. Store Kit llama a este método después de que StartDownloads se desencadene en UpdatedTransactions. Este método se llama varias veces a intervalos indeterminados para proporcionarle el progreso de descarga y, a continuación, una vez finalizada la descarga. Observe que el método acepta una matriz de objetos SKDownload, por lo que cada llamada al método puede proporcionarle el estado de varias descargas en la cola. Como se muestra en la implementación siguiente, los estados de descarga se comprueban cada vez que se realizan las acciones adecuadas.

// ENTIRELY NEW METHOD IN iOS6
public override void PaymentQueueUpdatedDownloads (SKPaymentQueue queue, SKDownload[] downloads)
{
    Console.WriteLine (" -- PaymentQueueUpdatedDownloads");
    foreach (SKDownload download in downloads) {
        switch (download.DownloadState) {
        case SKDownloadState.Active:
            // TODO: implement a notification to the UI (progress bar or something?)
            Console.WriteLine ("Download progress:" + download.Progress);
            Console.WriteLine ("Time remaining:   " + download.TimeRemaining); // -1 means 'still calculating'
            break;
        case SKDownloadState.Finished:
            Console.WriteLine ("Finished!!!!");
            Console.WriteLine ("Content URL:" + download.ContentUrl);

            // UNPACK HERE! Calls FinishTransaction when it's done
            theManager.SaveDownload (download);

            break;
        case SKDownloadState.Failed:
            Console.WriteLine ("Failed"); // TODO: UI?
            break;
        case SKDownloadState.Cancelled:
            Console.WriteLine ("Canceled"); // TODO: UI?
            break;
        case SKDownloadState.Paused:
        case SKDownloadState.Waiting:
            break;
        default:
            break;
        }
    }
}

InAppPurchaseManager (SKProductsRequestDelegate)

Esta clase contiene un nuevo método SaveDownload al que se llama después de que cada descarga se complete correctamente.

El contenido hospedado se ha descargado correctamente y descomprimido en el directorio Cache. Estructura de . El archivo PKG requiere que todos los archivos se guarden en un subdirectorio Contents, por lo que el código siguiente extrae los archivos del subdirectorio Contents.

El código recorre en iteración todos los archivos del paquete de contenido y los copia en el directorio Documents, en una subcarpeta denominada para el ProductIdentifier. Por último, llama a CompleteTransaction, que llama a FinishTransaction para quitar la transacción de la cola de pago.

// ENTIRELY NEW METHOD IN iOS 6
public void SaveDownload (SKDownload download)
{
    var documentsPath = Environment.GetFolderPath (Environment.SpecialFolder.Personal); // Documents folder
    var targetfolder = System.IO.Path.Combine (documentsPath, download.Transaction.Payment.ProductIdentifier);
    // targetfolder will be "/Documents/com.xamarin.storekitdoc.montouchimages/" or something like that
    if (!System.IO.Directory.Exists (targetfolder))
        System.IO.Directory.CreateDirectory (targetfolder);
    foreach (var file in System.IO.Directory.EnumerateFiles
             (System.IO.Path.Combine(download.ContentUrl.Path, "Contents"))) { // Contents directory is the default in .PKG files
        var fileName = file.Substring (file.LastIndexOf ("/") + 1);
        var newFilePath = System.IO.Path.Combine(targetfolder, fileName);
        if (!System.IO.File.Exists(newFilePath)) // HACK: this won't support new versions...
            System.IO.File.Copy (file, newFilePath);
        else
            Console.WriteLine ("already exists " + newFilePath);
    }
    CompleteTransaction (download.Transaction); // so it gets 'finished'
}

Cuando se llama a FinishTransaction, ya no se garantiza que los archivos descargados estén en el directorio Cache. Todos los archivos deben copiarse antes de llamar a FinishTransaction.

Otras consideraciones

El código de ejemplo anterior muestra una implementación bastante sencilla de la compra de contenido hospedado. Hay algunos puntos adicionales que debe tener en cuenta:

Detección de contenido actualizado

Aunque es posible actualizar los paquetes de contenido hospedado, Store Kit no proporciona ningún mecanismo para insertar estas actualizaciones en los usuarios que ya han descargado y comprado el producto. Para implementar esta funcionalidad, el código puede comprobar la nueva propiedad SKProduct.ContentVersion (si el SKProduct es Downloadable) periódicamente y detectar si se incrementa el valor. Como alternativa, podría crear un sistema de notificaciones push.

Instalación de versiones de contenido actualizadas

El código de ejemplo anterior omite la copia de archivos si el archivo ya existe. Esta no es una buena idea si desea admitir versiones más recientes del contenido que se va a descargar.

Una alternativa podría ser copiar el contenido en una carpeta denominada para la versión y realizar un seguimiento de cuál es la versión actual (por ejemplo, en NSUserDefaults o donde almacene los registros de compra completados).

Restaurar transacciones

Cuando se llama a SKPaymentQueue.DefaultQueue.RestoreCompletedTransactions, Store Kit devuelve todas las transacciones anteriores para el usuario. Si han comprado un gran número de elementos, o si cada compra tiene paquetes de contenido grandes, la restauración podría dar lugar a una gran cantidad de tráfico de red, ya que todo se pone en cola para su descarga a la vez.

Considere la posibilidad de realizar un seguimiento de si un producto se ha comprado por separado de la descarga real del paquete de contenido asociado.

Pausar, reiniciar y cancelar descargas

Aunque el código de ejemplo no muestra esta característica, es posible pausar y reiniciar las descargas de contenido hospedado. El SKPaymentQueue.DefaultQueue tiene métodos para PauseDownloads, ResumeDownloads y CancelDownloads.

Si el código llama a FinishTransaction en la cola de pago antes de que la descarga se Finished, esa descarga se cancela automáticamente.

Establecer la marca SKIP-Backup en el contenido descargado

Las directrices de copia de seguridad de iCloud de Apple sugieren que el contenido que no sea de usuario que se restaure fácilmente desde un servidor debe no se realizar una copia de seguridad (ya que usaría innecesariamente el almacenamiento de iCloud). Para obtener más información sobre cómo establecer el atributo de copia de seguridad, consulte la documentación del sistema de archivos de.

Resumen

En este artículo se han introducido dos nuevas características del Kit de la Tienda en iOS6: comprar iTunes y otro contenido desde la aplicación, y usar el servidor de Apple’para hospedar sus propias compras desde la aplicación. Esta introducción debe leerse junto con la documentación de compra desde la aplicación existente para una cobertura completa de la implementación de la funcionalidad del Kit de la Tienda.