Construyendo Plugins para iOS
Personalizando Solicitudes WWW en iOS

Preparando su aplicación para “In App Purchases” (Compras dentro de la aplicación)

Este capitulo no describe cómo integrar su juego con el API StoreKit de Apple. Es asumido que usted ya tiene integración con StoreKit vía un plugin de código nativo.

La documentación del StoreKit de Apple define cuatro tipos de productos que pueden ser vendidos vía el proceso de In App Purchase:

  • Contenido
  • Funcionalidad
  • Servicios
  • Subscripciones

Este capitulo cubre el primer caso solamente y se centrar principalmente en el concepto de contenido descargable. AssetBundles son recomendados para implementar contenido descargable en Unity y ambas las creación y el uso de tiempo de ejecución de los AssetBundles serán cubiertos aquí.

Exportando sus assets para uso en iOS

A veces es más útil mantener proyectos separados para su aplicación principal y los AssetBundles descargables que va a utilizar. Sin embargo, usted debería tener en cuenta que todos los scripts referenciados por objetos en el AssetBundle deben estar presente en el ejecutable principal de juego. El proyecto que usted utilice para crear el AssetBundle debe tener iOS seleccionado como el objeto de construcción debido a que el contenido de los archivos AssetBundle no es compatible entre iOS y otras plataformas.

Los AssetBundles son creados utilizando scripts de editor - un ejemplo simple es dado a continuación:-

// C#
using UnityEngine;
using UnityEditor;

public class ExportBundle : MonoBehaviour {
    [MenuItem ("Assets/Build AssetBundle From Selection - Track dependencies")]
    static void DoExport() {
        string str = EditorUtility.SaveFilePanel("Save Bundle...", Application.dataPath, Selection.activeObject.name, "assetbundle");
        if (str.Length != 0) {
            BuildPipeline.BuildAssetBundle(Selection.activeObject, Selection.objects, str, BuildAssetBundleOptions.CompleteAssets, BuildTarget.iPhone);
        }
    }
}

// JS
@MenuItem ("Assets/Build AssetBundle From Selection - Track dependencies")
static function ExportBundle() {
    var str : String = EditorUtility.SaveFilePanel("Save Bundle...", Application.dataPath, Selection.activeObject.name, "assetbundle");
    if (str.Length != 0) {
        BuildPipeline.BuildAssetBundle(Selection.activeObject, Selection.objects, str, BuildAssetBundleOptions.CompleteAssets, BuildTarget.iPhone);
    }
}

Usted debería guardar este código en un archivo llamado ExportBundle y colocarlo dentro una carpeta llamada Editor (usted puede simplemente crear esto si todavía no está presente en los proyectos). El script va a agregar un elemento del menú llamado “Build AssetBundle From Selection - Track dependencies” en el menú de Assets en el editor.

El contenido que usted quiere incluir en el paquete deberían estar preparadas en la forma de prefabs. Seleccione un prefab en la vista del proyecto y luego seleccione Assets > Build AssetBundle From Selection - Track dependencies (ie, el elemento del menú agregado por el script ExportBundle script). Este comando va a traer un dialogo para guardar dónde usted puede escoger el nombre y ubicación de su archivo AssetBundle.

Descargando sus assets en iOS

Tenga en cuenta: Apple puede cambiar las ubicaciones de la carpeta dónde usted está permitido escribir data. Siempre revise la última documentación de Apple para estar seguro que su aplicación será compatible. El siguiente consejo fue correcto hasta principios de 2013.

Los AssetBundles pueden ser descargados utilizando WWW class y una vez la transferencia haya completado, los assets encerrados pueden ser visitados. La manera recomendada de descargar un AssetBundle es utilizar LoadFromCacheOrDownload como es mostrados en el siguiente ejemplo:-


// C#
IEnumerator GetAssetBundle() {
    WWW download;
    string url = "http://somehost/somepath/someassetbundle.assetbundle";

    while (!Caching.ready)
        yield return null;

    download = WWW.LoadFromCacheOrDownload(url, 0);

    yield return download;

    AssetBundle assetBundle = download.assetBundle;
    if (assetBundle != null) {
        // Alternatively you can also load an asset by name (assetBundle.Load("my asset name"))
        Object go = assetBundle.mainAsset;
            
        if (go != null)
            Instantiate(go);
        else
            Debug.Log("Couldn't load resource");    
    } else {
        Debug.Log("Couldn't load resource");    
    }
}

// JS
function GetAssetBundle() {
    var download : WWW;
    var url = "http://somehost/somepath/someassetbundle.assetbundle";
    var download = WWW.LoadFromCacheOrDownload (url, 0);

    yield download;

    var assetBundle = download.assetBundle;
    if (assetBundle != null) {
        // Alternatively you can also load an asset by name (assetBundle.Load("my asset name"))
        var go : Object = assetBundle.mainAsset;
            
        if (go != null)
            Instantiate(go);
        else
            Debug.Log("Couldn't load resource");    
    } else {
        Debug.Log("Couldn't load resource");    
    }
}

Los archivos del asset bundle descargados son almacenados en la carpeta Library de la aplicación iOS sandbox y tiene la flag No Backup configurada en ellas. Esto significa que el OS no va a borrar estos archivos de manera accidental y estos archivos no tendrá copia de seguridad en iCloud. Es una buena idea mantener el limite del tamaño de cache bajo, para prevenir su aplicación de agarrar todo el espacio del disco del dispositivo.

Si usted necesita escoger exactamente dónde el archivo del AssetBundle está almacenado, usted puede utilizar una descarga estándar WWW (ie, simplemente utilice el constructor más bien de LoadFromCacheOrDownload) y luego guarde la información descargada en el disco utilizando el archivo API .NET. Usted puede guardar los archivos requeridos a la carpeta Application.temporaryCachePath (almacenada en Library/Caches que es regularmente “limpiada” por el OS) o la carpeta Application.persistentDataPath (almacenada en Documents la cual no es limpiada por el OS). Usted debería configurar la flag No Backup en estos archivos con iPhone.SetNoBackupFlag para prevenir que ellos tengan copia en iCloud.

Tenga en cuenta: Si usted no tiene configurada la flag No Backup, su aplicación puede ser rechazada cuando usted la publique a la App Store.

Usted puede acceder a los archivos guardados creando un objeto WWW con el URL de la forma file:///pathtoyourapplication/Library/savedassetbundle.assetbundle:-

// C#
string cachedAssetBundle = Application.temporaryCachePath + "/savedassetbundle.assetbundle"; 
System.IO.FileStream cache = new System.IO.FileStream(cachedAssetBundle, System.IO.FileMode.Create);
cache.Write(download.bytes, 0, download.bytes.Length);
cache.Close();

iOS.Device.SetNoBackupFlag(cachedAssetBundle);

Debug.Log("Cache saved: " + cachedAssetBundle);

// JS
private var cachedAssetBundle : String = Application.temporaryCachePath + "/savedassetbundle.assetbundle"; 
var cache = new System.IO.FileStream(cachedAssetBundle, System.IO.FileMode.Create);
cache.Write(download.bytes, 0, download.bytes.Length);
cache.Close();

iOS.Device.SetNoBackupFlag(cachedAssetBundle);

Debug.Log("Cache saved: " + cachedAssetBundle);

Tenga en cuenta: Usted puede probar la lectura de los archivos almacenados en la carpeta Documents si usted activa file sharing (configuración UIFileSharingEnabled a true en su Info.plist le permite a usted acceder a la carpeta de Documents de iTunes). Tenga en cuenta que los contenidos de la carpeta de Documents son cached al iCloud, entonces usted no debería utilizar esta ubicación para almacenar AssetBundles en la construcción final para ser enviada. Vea File System Basics en la documentación iOS de Apple para más detalles.

Construyendo Plugins para iOS
Personalizando Solicitudes WWW en iOS