Archivo de la etiqueta: adobe

Adobe AIR XIII – Copiar y pegar desde un DataGrid a Excel

Una de las típicas cosas que necesitamos siempre en una aplicación que presenta una lista de datos es la opción de exportar a Excel. En el caso del que hablamos hoy, necesitaba copiar los datos que se presentaban en un DataGrid de una aplicación AIR. La solución fácil habría sido lanzar una tarea de servidor que, con ayuda de alguna librería de conversión a formato Excel, devolviese el archivo xls. Pero no me gustaba la idea ya que implicaba una latencia absurda, si ya tengo los datos en mi aplicación, ¿por qué pedirlos de nuevo al servidor?

La solución que se me ocurrió es muy sencilla, copiar los datos del DataGrid al portapapeles de manera que se puedan pegar en un archivo Excel automáticamente, y que, por supuesto, mantenga el formato.

Lo complicado de todo esto no es copiar los datos sino mantener las columnas. En realidad no es que sea difícil, más bien hay que saber como generar la cadena de texto para que Excel la entienda. La solución es simplemente generar una cadena de valores separados por tabuladores y copiarla al portapapeles, automáticamente al pegar en Excel éste entenderá el formato de columnas y filas a la perfección.

Sabiendo la teoría, pasemos a la práctica. Lo que haremos será, para el DataGrid en cuestión, recorrer una a una todas sus columnas y recuperar el valor del DataProvider en ella. Tan sencillo como esto:

private function DataGridToExcel(dataGrid:DataGrid):String{
	var cadena:String = "";
	var valor:String = "";
	var saltodeLinea:String = "n";
	var data:Array;

	if (Capabilities.os.indexOf( "Mac" ) >= 0)
       	    saltodeLinea="r";

	for (var i:int = 0;i< dataGrid.columns.length-1)
            cadena+= '"' + dataGrid.columns[i].dataField+ '"';
            if (i < dataGrid.columns.length-1)
                cadena+= "t" ;
	}
	cadena+= saltodeLinea; 

	data= ArrayCollection( dataGrid.dataProvider ).source;

	for each (var item:Object in data){
		for(var k:int=0; k < dataGrid.columns.length; k++) {
			if (dataGrid.columns[k].labelFunction != undefined){
				valor= dataGrid.columns[k].labelFunction(item, dataGrid.columns[k]);
			}else{
				valor= item[ dataField ];
			}

			var pattern:RegExp;
			if (valor){
				pattern = /["]/g;
				valor= value.replace( pattern, "" );
				valor= '"' + valor+ '"';
			}else{
				valor= '""';
			}
			cadena+= valor;
			if (k < dataGrid.columns.length - 1){
				cadena+= "t";
			}
		}
		cadena+= saltodeLinea;
	}
	return cadena;
}

A mi me gusta añadir la opción como menú contextual del DataGrid, de manera que al hacer click con el botón derecho sobre el mismo se abra un menú con la entrada “Copiar a Excel“. Para hacerlo de manera reutilizable podemos hacer una llamada de este estilo en los DataGrid donde queremos utilizarlo:

private function addCopyEventDtg(dtg:DataGrid):void{
	var _contextMenu:NativeMenu=new NativeMenu();
	var _copyMenuItem:NativeMenuItem = _contextMenu.addItem(new NativeMenuItem("Copiar a Excel"));
	_copyMenuItem.addEventListener(Event.SELECT, function(event:Event):void {
		System.setClipboard( DataGridToExcel(dtg) );
	});
	dtg.contextMenu=_contextMenu;
}

Y lo lanzamos de la manera más obvia:

addCopyEventDtg(nombreDeTuDataGrid);

Este sería el resultado:

No se a vosotros, a mi me sirve :P, y queda muy aparente la cosa :).

Adobe Air XII – No se puede instalar la aplicación, este instalador no se ha configurado correctamente

Recientemente he tenido que modificar una aplicación AIR y, ya de paso, me dio por convertirla a Air2. Todo iba bien hasta que la subí al servidor para que a todos los usuarios les apareciese automáticamente la actualización pero una vez comenzaba la instalación salía el siguiente mensaje:

No se puede instalar la aplicación, este instalador no se ha configurado correctamente

Tras googlear un poco lo único que encontré es que normalmente se debe a que la has publicado con un certificado distinto al que tenía la versión anterior, pero no era mi caso. Y así, de repente, me acordé que para utilizar la instalación automática se necesitaba el publisherID y pensé, ¿no será algo de eso?.

Así es que revisé el descriptor de la aplicación Aplicacion-app.xml y me encontré con un nuevo nodo comentado:

<publisherID></publisherID>

Lo descomenté y le añadí mi publisherID que se obtiene de la versión anterior instalada en:

RUTA_DE_INSTALACION_DE_TU_APPMETA-INFAIRapplication.xml

Publicas de nuevo la aplicación y todo solucionado, se actualiza perfectamente :).

Adobe Air XI – Despliega tus aplicaciones directamente desde la web

Vuelvo con un artículo sobre la serie que hice hace algún tipo acerca de Adobe Air.

Uno de los principales problemas con los que me he encontrado al desarrollar con Air es a la hora del despliegue, ya que los clientes deben instalarse primero el framework y después la aplicación, lo que da lugar a muchas dudas y potenciales problemas. Para solucionarlo existe una librería de Adobe que permite saber si un cliente tiene instalado el framework y tu aplicación directamente desde una página web y lanzar la instalación de ambos en caso de que no los tenga, de esta manera los usuarios no tienen que descargar nada, todo muy sencillo e intuitivo.

Para interactuar con esta librería existe además una pequeña aplicación Flash que se distribuye con el sdk de Flex con los conceptos básicos: comprobar si el cliente tiene el framework y lanzar la instalación si es necesario. La podéis encontrar en:

C:Archivos de programaAdobeAdobe Flash Builder 4sdks4.0.0samplesbadge

Sin embargo puede ser realmente tedioso configurarla y programarla adecuadamente, así que existe Badger, una aplicación AIR que enmascara todo este proceso con un sencillo asistente donde rellenas los parámetros, incluidas las cadenas de texto a utilizar, y te genera el código necesario. Puedes descargarla aquí.

Al ejecutarla veremos la pantalla principal.

Por defecto solo hay un template, así que el primer menú lo podemos obviar. Con el segundo seleccionas tu aplicación AIR para que Badger cargue automáticamente algunos de los parámetros y, cuando has terminado, con la última opción “Export badge” generas el código.

Dentro de la configuración hay dos campos importantes. “application url“, debes introducir la url completa (con http://) desde donde se descargará la aplicación, y “publisher ID“, donde tienes que seleccionar la ruta donde la tienes instalada localmente para que Badger lea automáticamente este dato, imprescindible para comprobar si el cliente ya la tiene instalada.

Al subir todos los archivos generados a tu web (el html puedes integrarlo adecuadamente) y cargar la url en un navegador verás algo parecido a esto suponiendo que no tienes la aplicación (o el framework) instalados.

Al hacer click en “Instalar”, si no tienes el framework instalado, te pedirá autorización y comenzará la descarga:

Para finalmente acabar instalando tu aplicación.

Si el cliente ya tuviese la aplicación instalada podremos lanzarla automáticamente también. Para conseguirlo es necesario, primero, que en el descriptor de la aplicación hayas configurado el siguiente parámetro a “true“:

<allowBrowserInvocation>true</allowBrowserInvocation>

Ahora, si el cliente ya tiene nuestra aplicación, veremos algo como esto:

Y al hacer click en “Lanzar ahora” nuestra aplicación se cargará ella sola :).

Como veis es muy sencillo para el cliente instalar así nuestras aplicaciones AIR, nada que ver con tener que descargar el framework por un lado y la aplicación por el otro.

Sobre diseñadores, programadores y formación

El pasado sábado un buen amigo me pidió que le acompañase a un seminario sobre Flex. No me apetecía mucho, y menos aún madrugar un fin de semana, pero es lo que tiene la amistad. Al final resultó que era un pequeño avance de lo que sería un curso de formación continua de 30 horas sobre desarrollo de RIA con Flex3. El profesor era programador profesional y bastante majete, pero mi sorpresa llegó cuando preguntó a la sala por el perfil profesional que teníamos. Para un curso de desarrollo había aproximadamente 28 diseñadores sobre 30 personas. Mi cara de asombro fue abrumadora, alguien no había entendido de qué iba la movida. Mi amigo, perro viejo ya en estas lides, no se cortó un pelo y comenzó a preguntar sobre las salidas de una herramienta como Flex para un diseñador, y ahí llegó lo peor, el profesor hizo una defensa a ultranza de las posibilidades que tenía, obviamente siempre bajo su punto de vista de programador, para muestra un botón:

Es muy sencillo, no tienes que saber programación, casi todo se hace con una línea de código. Yo tardé muy poco en comenzar a trabajar, aunque es verdad que tenía experiencia programando en muchos otros lenguajes.

De verdad, yo estaba alucinando. Lo peor es que convenció a mucha gente, y no lo digo por él, que me parece fenomenal que se gane un dinero, lo digo por la utilidad de un curso así para un diseñador. Tampoco debemos olvidarnos del otro lado de la ecuación. Con lo fácil que es hoy en día informarte y documentarte sobre una herramienta, la gente acude sin saber absolutamente nada acerca de lo que es Flex y para qué sirve.

En mi humilde opinión hubiese mejorado considerablemente el curso si hubiese optado por cambiar la orientación hacia skining puro y duro en Flex, una de las tareas más complicadas (los programadores tampoco son diseñadores) y a la vez desconocidas y con más salidas (bajo mi punto de vista), pero claro, él tampoco tenía los conocimientos adecuados para dar un curso de diseño, así son las cosas. En varios momentos de la charla hizo referencia a Adobe Flash Catalyst, la nueva gran herramienta de Adobe que llevará a desarrollar RIA’s de próxima generación, la simbiosis perfecta entre diseño y programación, pero se limitó a decir cosas como: “según la demo que nos hicieron en junio“, “por lo poco que he visto“… ¡Podías haberla probado tu mismo! Y es que os aseguro que será una revolución, una integración absoluta entre apariencia y funcionalidad.

Y todo esto me lleva al meollo de la cuestión: la gran mentira de la formación (de cualquier tipo) en este país. A principios de esta década impartí varios cursos, se pagaban muy bien y era una muy buena oportunidad, pero mi ética me obligó a abandonar la formación. Os pondré un par de ejemplos:

  • Allá por 2000 impartí un curso de 20 horas sobre Windows NT (¿quien se acuerda de eso? 😛 ) para trabajadores de Xerox. Patético. A los asistentes lo único que les interesaba era saber configurar una impresora en una red local, el resto les daba absolutamente igual. Claro, imaginaos el estado anímico de la  gente cuando lo que les interesa de verdad no llega casi hasta el final… Da igual que necesites saber qué son privilegios de administrador o colas de impresión, ellos sólo querían que les explicase lo que necesitaban para su trabajo diario, lógico también.
  • Un año después impartí la parte práctica de un curso sobre comercio electrónico organizado por la Universidad Politécnica de Valencia.  Mi clase versaba sobre el desarrollo de una tienda electrónica (bases de datos, programación, pasarela de pagos…). ¿La audiencia? Estudiantes de últimos cursos de derecho, empresariales, psicología… ya se sabe, créditos de libre elección. ¿A quien se le ocurrió incluir algo tan técnico en el programa de este curso?

Este último ejemplo me llevó a mi primer desengaño con la formación. Las negociaciones las llevé a cabo con una de las cabezas más visibles de la Universidad Politécnica (no diré nombres 😛 ). Un día, comiendo juntos, este personaje me soltó tan libremente:

Tú, si quieres hacer un curso, no tienes más que decírmelo. Preparas un programa, me dices cuánto te quieres llevar, vemos cual sería el coste por alumno y del resto nos encargamos nosotros. Al ser cursos patrocinados por la Universidad siempre hay gente dispuesta a apuntarse y pagar lo que haga falta.

¡Qué inocente era yo de aquélla! Podía haberme forrado pero preferí dejarlo para quien no tuviese problemas morales, no entendía que en un curso medianamente técnico se mezclase gente de perfiles tan dispares llevando la utilidad del mismo al mero canje de créditos o a un diploma con el que rellenar un curriculum.

En aquellos días llegó mi divorcio definitivo con la formación. Acudí a una entrevista en una de esas empresas líderes en Valencia, de esas que se dedican a impartir cursos para certificaciones. Querían organizar un curso sobre desarrollo en C bajo Linux. Os recuerdo que hablamos de 2001, así que me pareció alucinante que a alguien se le ocurriese montar algo de ese calado, si aún hoy es raro ver un curso así imaginaos hace ocho años. Mi conversación terminó casi en discusión, a modo de resumen:

  • Yo:  ¿A qué perfil de alumnos va orientado el curso?
  • NI: A cualquiera que se apunte y pague.
  • YO: No, a ver, no puedes mezclar en un mismo curso a gente que no ha visto Linux en su vida, gente que no sabe programar, gente que ya programa en C bajo Windows y quiere cambiar, gente que tiene conocimientos básicos de programación…
  • NI: ¿Cómo que no? Con que paguen…
  • YO: Pero vamos a ver, ¿quieres que la gente aprenda algo y aprovechen el curso?
  • NI: (silencio…)

Ahí entendí que esto no estaba hecho para mi. No podía engañar así a la gente.
Y esto me lleva de vuelta al comienzo del artículo. De nuevo por aquella época (2001) este amigo mío, en sus ansias por mejorar como diseñador, se planteó tener unos conocimientos mínimos de programación que le permitiesen hacer cosas básicas por su cuenta, así que se me apunta en este último sitio del que os he hablado a un curso sobre Visual Basic 6. Sabéis cómo acabó la historia ¿no? Creo que no llegó ni a asistir una semana.

Esto es una mi@3%6, estoy yo que no tengo ni idea, están los que vienen a clase a plantear problemas que tienen en su trabajo y ver como resolverlos (ya programadores), están los que les da todo igual… imposible aprender nada. Si explica a los que saben, nosotros no nos enteramos de nada, y si nos explica a nosotros los demás se aburren.

Esto, queridos lectores, es la formación (al menos la técnica): dinero, subvenciones y más dinero. Ah, y adelgazar las cifras del paro, no nos olvidemos 😉 . Ah, y lo más triste de todo, no ha cambiado nada en los últimos años, incluso diría que vamos a peor.

Adobe AIR X – Obtener el número de versión de una aplicación durante la ejecución

Parece simple pero, pese a que hay métodos para casi todo en Adobe AIR, no hay manera de saber en tiempo de ejecución el número de versión de una aplicación. ¿Para qué puedes necesitarlo? Pues por ejemplo, como es mi caso, para mostrar la típica pantallita “Acerca de…” donde indiques automáticamente el número de versión. Me diréis, bueno, si, pero puedes tener una variable que actualices con cada cambio de versión. Claro, pero entonces tendría que acordarme de actualizarlo en tres puntos: esta nueva variable, el descriptor de la aplicación y el archivo XML de autoactualización. Si puedo eliminar uno de ellos ¿por qué no hacerlo?

[Bindable]
private var airApplicationVersion:String = "";

private function getVersion():void{
 var appXML:XML = NativeApplication.nativeApplication.applicationDescriptor;
 var air:Namespace = appXML.namespaceDeclarations()[0];
 this.airApplicationVersion = appXML.air::version;
}

Así de fácil tendremos una variable “bindeable” para mostar el número de versión, por ejemplo:

<mx:Text text="Versión {airApplicationVersion}"/>

Espero que os sea útil 🙂 .

Adobe AIR VIII – Información encriptada y persistente

Ya hemos visto como trabajar con bases de datos con AIR, sin embargo he deubierto un nuevo método para conservar datos que puede resultar especialmente útil para mantener información sensible, como claves de acceso a servicios, ya que se guarda encriptada. Hablamos de la clase EncryptedLocalStore.

Una de las peculiaridades de esta clase es que es persistente mientras la aplicación no borre sus contenidos, ya que aunque se desinstale los datos siguen ahí, lo que resulta especialmente útil si tus aplicaciones son de pago (guardar licencias) o tienen periodos de prueba (así no se podrá utilizar de nuevo al desinstalar y volver a instalarla).

Cada aplicación dispone de su propia EncryptedLocalStore con lo que los datos que se guarden en una no interferirán con los de otra.

EncryptedLocalStore tiene sólamente tres métodos estáticos (no es necesario instanciar la clase) que permiten guardar, leer y eliminar datos.

  • setItem(“nombre”, valor):  guarda un dato.
  • getItem(“nombre”):  lee el dato.
  • removeItem(“nombre”):  elimina los datos.

Para dar mayor versatilidad al sistema, los datos a guardar deben ser del tipo ByteArray, así que se podrá guardar cualquier dato que se pueda convertir a este tipo y no sólo cadenas de texto.

Veamos un ejemplo:

//guardar datos
var clave:String = "password";
var bytes:ByteArray = new ByteArray();
bytes.writeUTFBytes(str);
EncryptedLocalStore.setItem("clave", bytes);

//leer datos
var datos:ByteArray = EncryptedLocalStore.getItem("clave");
var miclave:String=datos.readUTFBytes(datos.length));

//eliminar datos
EncryptedLocalStore.removeItem("clave");

Extremadamente sencillo y útil, no se como no lo había visto antes, creo que pasa bastante desapercibida esta manera de guardar datos en la documentación.

De esta manera podemos guardar datos sin necesidad de bases de datos. Eso sí, al parecer no deben exceder los 10mb o comenzaremos a tener problemas de rendimiento. Recuerda lo que decía al principio, aunque el usuario desinstale la aplicación los datos de EncryptedLocalStore siguen en su sistema operativo.

Adobe AIR VII – Detectar el modo de inicio de la aplicación

Bueno, pues antes de lo previsto tengo que hacer el primer añadido a la serie de Adobe Air que creía ya terminada 😛 .

La primera curiosidad de hoy se refiere a conseguir que nuestra aplicación se inicie automáticamente al identificarte en el sistema operativo. Muy sencillo:

try{
    NativeApplication.nativeApplication.startAtLogin=true;
}catch(e:Error){
    //el sistema operativo no soporta la opcion
}

Con esto conseguimos que se inicie sóla, pruébalo 😉 . Deberías dejar una opción en algún lado de tu aplicación para que el usuario desactive esta posibilidad, no a todo el mundo le gusta.

La nueva versión 1.5.1 de AIR trajo consigo una interesante funcionalidad para saber si nuestra aplicación ha sido iniciada a mano por el usuario o se ha iniciado automáticamente con el sistema operativo, pero para conseguir que funcione debemos seguir algunos pasos.

Primero debemos actualizar el sdk de AIR a la versión mas reciente desde aquí. Si el sdk de Flex es anterior al 3.3 deberías actualizarlo también desde aquí. El de Flex se descomprime en la carpeta “sdks” de tu instalacion de Flex Builder, el de AIR se descomprime dentro del sdk de Flex que has instalado antes o en el que ya tienes.

Ahora arrancamos Flex Builder y lo primero que haremos será añadir el nuevo SDK de Flex (si lo has instalado) a la lista de sdk’s disponibles. Desde tu proyecto, boton derecho, “Properties” y aquí vas a “Flex Compiler” y a “Configure Flex SDKs…“. Añades un nuevo sdk seleccionando la carpeta donde está instalado, aceptas y en la ventana anterior indicas que utilice este nuevo.

A continuación configuraremos la aplicación AIR donde queremos usar las nuevas funciones, para ello editamos el descriptor de la aplicación, el fichero xml donde se configuran las opciones, y arriba de todo dejaremos la segunda línea así:

<application xmlns="http://ns.adobe.com/air/application/1.5.1">

Es decir, que utiliza el namespace de la versión 1.5.1. Sólo eso.

Ya tenemos todo preparado. La nueva característica consiste en un método del evento InvokeEvent, reason, que nos indica precisamente eso, cómo fue iniciada la aplicación.

Simplemente debemos añadir a nuestra aplicación el detector adecuado y hacer lo que consideres oportuno dependiendo del tipo de iniciación.

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" invoke="detecta(event)">
    <mx:Script>
        <![CDATA[
            private function detecta(a:InvokeEvent):void{
                if(a.reason=="LOGIN"){
                    //la aplicacion se lanza automaticamente al hacer login
                }else{
                    //STANDARD
                    //La aplicacion se ejecuta manualmente
                }
            }
        ]]>
    </mx:Script>
</mx:WindowedApplication>

¿Qué utilidad puede tener? Pues además de las que se te ocurran a ti mismo, puede servir para mostrar o no la ventana de la aplicación si ésta se ha lanzado a mano o “a máquina”.  Por ejemplo, si nuestra aplicación, como vimos en el primer capítulo de esta serie, es de ésas que se quedan residentes en la barra de tareas, puedes iniciarla de distinto modo si la lanza el usuario a mano o si se inicia con el sistema operativo. Normalmente cuando lanzamos nosotros una aplicación esperamos ver la ventana de ésta para utilizarla, mientras que si se lanza sóla preferimos no ver nada, cuando se necesite ya sabemos que está en la barra de tareas y que con un click se abrirá.

Eso es todo. Interesante ¿no? 🙂 .

Adobe AIR y VI – Notificaciones instantáneas ó toast style windows

Llegamos, por fin, al último capítulo de esta serie sobre Adobe Air.

En el proyecto en el que estoy trabajando necesito que se lancen notificaciones ante determinados eventos en el servidor. Podría hacerlo abriendo ventanas normales, claro, pero son avisos que no requieren acción del usuario, sólo son mensajes, así que me gustaría que fuesen no intrusivos, que no molesten al usuario con lo que esté haciendo. Son los típicos mensajes que lanzan algunos programas de esos que se quedan como un icono en la barra de tareas (Messenger, McAfee…).

Tras mucho buscar llegué a la primera conclusión. Este tipo de ventanas las llaman “toast style windows” 😐 . El segundo paso era cómo hacerlas. Seguí buscando y encontré varias clases que implementaban lo que yo quería, si alguien lo ha hecho ya… ¿por qué reinventar la rueda?. Probé varios sistemas y el que más me convenció fue éste, directamente desde Adobe. Sencillamente lo controla todo, desde lanzar varias ventanas y que se apilen una sobre otra a lo alto del escritorio hasta controlar si el usuario está utilizando el ordenador o no para no eliminarlas sin que las vea. Sencillamente perfecto. Con algo de estilos pueden quedar muy bien.

Toast windows con AirEl ejemplo del que os hablo venía para hacer con Adobe Flash, no con Flex, pero se adapta sólo.

Lo primero que necesitaremos son las clases que lanzan las ventanas. Os las dejo aquí.

Y ahora las utilizamos en la aplicación.

import com.xplota.display.DisplayManager;
import com.xplota.display.MessageWindow;

private var displayManager:DisplayManager;

function nuevoMensaje(texto:String):void(){
    displayManager = new DisplayManager();
    displayManager.displayMessage(texto);
}

nuevoMensaje("prueba de nueva ventana");

Ya está! Eso es todo. Sencillo ¿eh? 😉 . Prueba a lanzar varias ventanas y verás como se apilan automáticamente unas sobre otras. Si haces click sobre una de ellas verás que desaparece, da igual en cual, deja ese hueco. Si esperas 10 segundos (configurables), verás que la ventana desaparece sóla, pero si no utilizas ni el teclado ni el ratón, el sistema supone que no estás viendo lo que ocurre y mantiene ahí los mensajes para que no los pierdas. No olvides diseñarlas un poco más chulas que las que trae por defecto 😛 .

Hasta aquí hemos llegado con este minicurso de AIR. Creo que he cubierto la mayoría de cosas que se necesitan para comenzar una aplicación decente en AIR, aún así es posible que añada alguno más, quién sabe…

Espero que os hayan sido útiles.

Adobe AIR V – Trabajando con bases de datos locales sqlite

Llegamos al penúltimo capítulo de esta serie acerca de Adobe AIR. Hoy veremos como trabajar en local con datos persistentes de manera que podamos recuperarlos en otras sesiones. Al decir en local me refiero a que no se necesita conexión a Internet para salvaguardarlos, no se utilizará una base de datos remota sino el propio ordenador del cliente.

A diferencia de las aplicaciones Flash embebidas en un navegador, AIR permite el acceso completo al sistema de archivos del sistema operativo, no tiene las limitaciones de la máquina virtual Flash ni las políticas de seguridad, así que podemos crear, abrir, modificar y guardar cualquier archivo.

Si unimos todo esto con sqlite obtenemos lo que buscamos ya que AIR trae soporte nativo para sqlite con lo que guardar y consultar datos con sentencias sql no será un problema, más sencillo imposible.

AIR permite dos modos de trabajo con sqlite, síncrono y asíncrono. La diferencia es obvia, en el primer tipo se espera a que la ejecución de las instrucciones sql termine para continuar la ejecución de la aplicación, mientras que en el modo asíncrono se utilizan eventos que se disparan cuando se da por finalizada la consulta. En modo sincrono debemos ejecutar todo enjaulado en estructuras try/catch para prevenir errores y excepciones.

Aunque puedes crear la base de datos directamente desde la propia aplicación con sentencias CREATE TABLE, yo prefiero distribuir la aplicación con la base de datos ya creada, es mucho más cómodo. Para crearlas suelo usar dos utilidades:

También puedes hacer tu propia aplicación AIR para gestionar bases de datos sqlite, no conozco ninguna pero sería muy útil. ¿Quién se atreve? 🙂

Con cualquiera de ellas podremos crear la estructura de nuestra base de datos que copiaremos en el directorio del código fuente, para que al compilarla y empaquetarla se distribuya con ella.

Como no todos los sistemas operativos permiten a cualquier usuario escribir en la ruta de instalación de las aplicaciones, lo mejor y más recomendable es copiar la base de datos “base” en la carpeta de usuario del cliente que está ejecutándola ya que ahí siempre tiene permisos. Para hacerlo AIR nos provee de todos los mecanismos necesarios.

Con los métodos userDirectory y applicationDirectory de la clase File accedemos a las rutas de usuario y de la aplicación respectivamente independientemente del sistema operativo sobre el que está corriendo la aplicación, con lo cual hacemos el proceso completamente transparente.

var a:File=File.userDirectory.resolvePath("basedatos.db");
if(!a.exists){
    var b:File=File.applicationStorageDirectory.resolvePath("basededatos.db");
    b.copyTo(a, true);
}

Sencillo y evidente, sobran más explicaciones. Sabiendo esto es ya muy fácil conectar a la base de datos. Utilicemos el método síncrono antes comentado.

private var dbFile:File;
private var conn:SQLConnection;
private var q:SQLStatement;  

private function iniciaDB():void {
    var dbFile:File=File.userDirectory.resolvePath("basededatos.db");
    if(!dbFile.exists){
        var b:File=File.applicationStorageDirectory.resolvePath("basededatos.db");
        b.copyTo(dbFile, true);
    }
    conn = new SQLConnection();
    try{
        conn.open(dbFile);
    }catch (error:SQLError){
        Alert.show("ERROR ABRIENDO BBDD "+error.message+" "+error.details);
    }
}

¡Ya estamos dentro de la base de datos! Sólo nos queda ejecutar consultas y recuperar los resultados. No tiene mucha ciencia. Veamos un ejemplo para que queda bien claro.

var q:SQLStatement;
var result:SQLResult;

q.text = "SELECT campo1, campo2 FROM tabla";

try{
   q.execute();
   result=q.getResult();
   if(result.data){
     var numResults:int = result.data.length;
     for (var i:int = 0; i < numResults; i++){
        var r:Object = result.data[i];
        //accedemos a los campos desde el objeto, r.campo1, r.campo2
     }
   }
}catch (error:SQLError){
  //la consulta nos ha devuelto un error
}

Eso es todo como iniciación sqlite desde AIR. Del mismo modo se pueden ejecutar instrucciones INSERT, DELETE

A partir de aquí puede seguir cualquiera 😛 .

En el próximo y último capítulo veremos como hacer ventanas de notificación instantáneas y no intrusivas, del estilo de los avisos de conexión del Messenger 😉 .

Adobe AIR IV – Detectando el estado de la conexión

Continuamos con la serie de artíulos sobre Adobe Air. Hoy trataremos un tema curioso como es detectar si el cliente dispone de conexión a Internet. ¿Qué utilidad puede tener saberlo? Sencillo, permitir que la aplicación trabaje en modos offline y online.

Esta parte viene bastante bien explicada en el manual. Existe un evento “NETWORK_CHANGE” que no sirve para nuestro propósito 😐 .  ¿Para qué sirve entonces? Para detectar cambios en las interfaces de red en general. Este evento se dispara cada vez que se producen modificaciones en alguna de las interfaces de red de la máquina que ejecuta la aplicación, lo que no quiere decir que cambie el estado de la conexión a Internet ya que este evento no sabe si hay o no salida a Internet ni a través de cual de las interfaces se sale. ¿Qué utilidad puede tener entonces? No lo sé 😛 , pero ahí está el evento por si lo quieres utilizar para algo…

NativeApplication.nativeApplication.addEventListener(Event.NETWORK_CHANGE, onNetworkChange);
function onNetworkChange(event:Event)
{
    //Check resource availability
}

Para nuestro propósito debemos utilizar la clase URLMonitor que, como su propio nombre indica, sirve para monitorizar una URL. En efecto, así es como AIR detecta el estado de la conexión, conectando periódicamente a la URL que le indiquemos. Si no puede alcanzarla asume que te has quedado sin salida a Internet. Vamos, que si estábais esperando algo superavanzado y chulo, podéis seguir esperando, es el método más tradicional que existe: leches, no puedo conectar con Google, habré perdido la wifi. Es lo mismo 😛 .

import air.net.URLMonitor;
import flash.net.URLRequest;
import flash.events.StatusEvent;

var monitor:URLMonitor;
monitor = new URLMonitor(new URLRequest('http://www.adobe.com'));
monitor.addEventListener(StatusEvent.STATUS, announceStatus);
monitor.start();

function announceStatus(e:StatusEvent):void {
    trace("Status change. Current status: " + monitor.available);
}

Dentro de la función, lo que nos interesa es el valor de monitor.available, true ó false, lo que nos indicará si podemos o no conectar con la URL. Éste es, en realidad, el concepto de URLMonitor, determinar si una URL es alcanzable o no. Que una URL no sea alcanzable no quiere decir que no tengas acceso a Internet, sólo que no tienes con aquella URL. La comprobación, por tanto, debería hacerse con la URL del backend de nuestra aplicación y no con cualquier URL en general ya que de quien depende nuestra aplicación es de nuestro backend, no de Google 😛 .

El mismo sistema se puede utilizar para comprobar el estado de cualquier aplicación que escuche en un puerto distinto al 80. La explicación sería exactamente la misma y lo haríamos de este modo:

import air.net.ServiceMonitor;
import flash.events.StatusEvent;

socketMonitor = new SocketMonitor('www.adobe.com',6667);
socketMonitor.addEventListener(StatusEvent.STATUS, socketStatusChange);
socketMonitor.start();

function announceStatus(e:StatusEvent):void {
    trace("Status change. Current status: " + socketMonitor.available);
}

En el próximo capítulo veremos cómo añadir potencia a nuestras aplicaciones utilizando sqllite para guardar datos offline. Si combinamos la posibilidad de guardar datos en la aplicación con la de comprobar el estado de red contra el backend podremos hacer que nuestra aplicación funcione en modo offline guardando lo que necesitase enviar y procesándolo cuando tenga conexión. Creo que no se ha entendido bien, pongamos un ejemplo práctico.

Tengo una aplicación que permite enviar SMS a móviles a través de una pasarela HTTP que será quien haga los envíos. Mi aplicación pide el número de destino y el texto a enviar, conecta con la pasarela y le pasa el mensaje que quiero enviar. Como es lógico, si en el momento de enviar no tengo conexión con la pasarela, no podré enviar el SMS. Tengamos ahora presente lo que acabamos de ver en este artículo… ¡puedo saber en cada momento si la pasarela HTTP es alcanzable!  Si cuando voy a hacer el envío no tengo conexión, los guardo en mi base de datos sqllite y cuando cambie el estado de la conexión (URLMonitor me avisará) lanzo todos los envíos pendientes.

Seguro que si lo piensas un poco tú también le encuentras alguna utilidad 🙂 . Lo dicho, en el próximo capítulo… sqllite.