FileReference.download() falla, no descarga el archivo, no hace nada

A diferencia de una aplicación Adobe Air, cuando esta se compila en un archivo Flash (SWF), el método Download() de la clase FileReference despliega la ventana para almacenar el archivo pero este no es descargado, simplemente no ocurre nada.

Adobe sabe de este problema y lo postea acá: http://kb2.adobe.com/cps/363/3637d5c3.html

La solución es sencilla:

El método Download falla sólo cuando la clase FileReference es instanciada dentro de una función local. Para solucionar el problema basta con declararla de manera global. Ejemplos:

De esta forma el método Download no hará nada:

function downloadFile():void {
var fileRef:FileReference = new FileReference(); //FileReference com ámbito local
fileRef.download(new URLRequest(“myFile.txt”), “myFile.txt”);
}

De esta manera el método Download descargará el archivo y lo almacenará en el directorio elegido por el usuario:

private var fileRef:FileReference = new FileReference(); //FileReference com ámbito global
function downloadFile():void {
fileRef.download(new URLRequest(“myFile.txt”), “myFile.txt”);
}

Aplicando efectos a Labels, LinkButtons, Buttons, etc…

Si ya haz jugado con los efectos tan fácil de aplicar que tiene FLEX, te podrás haber dado cuenta que existen ciertos componentes que no “agarran” los efectos o no se animan. Esto ocurre cuando el componente es un Label (etiqueta) o en su defecto, posee un Label interno tal como un Button o un LinkButton. Por defecto, si aplicas un efecto a un Container (contenedor) todos sus hijos toman el efecto. Ejemplo, si creas un Canvas y le agregas un Label y un TextArea y le aplicas un efecto Fade (desvanecimiento) entonces cuando se este animando, solo el TextArea se verá desvanecer y el Label parecerá que aparece o se oculta de inmediato sin ese efecto transitorio de desvanecimiento.

Existen varios trucos para solventar esto. Uno es especificar literalmente a FLEX que tipo de fuente usará el Label. Es sencillo y se hace con una función setStyle pero por otro lado, tendrás que hacer lo mismo por cada Label, Button, …, que tengas en tu Container.

Acá propongo uno muy sencillo que te garantizará funcionar donde sea. Está en AS3. A nivel global creas un BlurFilter y un Array:

private var blur_filter:BlurFilter = new BlurFilter(0,0,0);
private var filtros:Array = new Array();

Luego, internamente en el código agregas el BlurFilter al Array:

filtros.push(blur_filter);

Y todo componente de FLEX tiene la propiedad filters. Bastará con asignar el Array filtros a la propiedad filter del Label, Button, LinkButton, …, para que mágicamente el texto de los Labels, o cualquier componente que tenga texo, se anime:

contenedor_u_objeto.filters = filtros;

Recuerda, basta con aplicar el filtro al contenedor, bien sea un Canvas, Panel, …, para que todos sus hijos se animen en conjunto sin importar que tipo de componentes sean 😛

Sentencia “WITH” para ahorrar código

Vaya que es tedioso cambiar el monton de propiedades de un objeto… Y FLEX suele prestarse para eso cuando se trabajan con estilos sin emplear CSS… Lo siguiente es un ejemplo de como usar la sentencia WITH para agrupar propiedades de un objeto.

Sin uso de la sentencia WITH un codigo en FLEX seria asi…

this.width = 600;
this.height = 300;
this.x = 800/2 – this.width/2;
this.y = 400/2 – this.height/2;
this.setStyle(“hideEffect”, this.parallel);
this.setStyle(“showEffect”, this.parallel);
this.bot_aceptar.label = “Aceptar”;

Usando WITH tendriamos algo menos amontonado…

with(this){
width = 600;
height = 300;
x = 800/2 – width/2;
y = 400/2 – height/2;
setStyle(“hideEffect”, parallel);
setStyle(“showEffect”, parallel);
bot_aceptar.label = “Aceptar”;
}

Security sandbox violation

Estaba haciendo una aplicación en FLEX que requiere el uso de AMFPHP para conectarme con una Base de Datos en Postgres y todo siempre funcionó bien, todo hasta que decidí acceder a mi aplicación desde una URL y no desde el .swf que se genera. El error descrito fue el siguiente:

Error #2044: Unhandled SecurityErrorEvent:. text=Error #2048: Security sandbox violation: http://localhost/SQR/bin-debug/SQR.swf cannot load data from http://127.0.0.1/amfphp/gateway.php.

Es un error muy común y fácil de solucionar. Se genera cuando una aplicación flash trata de acceder a datos que residen en otro dominio web. En mi caso, aunque no lo crean, es porque accedí a mi aplicacion desde mi servidor localhost y dentro de ella tengo un script que pide datos a un servicio bajo el dominio 127.0.0.1. Entonces se preguntaran, ¿no es localhost y 127.0.0.1 lo mismo?

Y mi respuesta es… “No necesariamente”. No es la primera vez que he tenidos problemas asi. Una vez, Windows dejó de reconocer el dominio localhost y debía acceder a mi servidor local siempre desde 127.0.0.1. La solución fue sencilla modificanddo un par de líneas en una subcarpeta de Windows -si ese es el caso de ustedes, googleenlo, es sencillo de resolver :P-

En el mejor de los casos, la solución se consigue cambiando todos los 127.0.0.1 por localhost o viceversa. Esto quiere decir que si en el AS3 tienes referencias a 127.0.0.1 entonces accede a tu aplicacion empleando la URL 127.0.0.1. Para cualquier IP o dominio aplica lo mismo.

En un entorno de producción real, esta modificacion ya no es viable. Para solucionarlo se crea un fichero en XML que va a permitir resolver el problema En este enlace Adobe publica la solución 🙂

Un mini juego de Damas en C

Hace un par de días una profesora en la universidad me pidió que por favor le hiciera de manera express un juego de damas en C a su sobrinita… Resulta que la muchacha estudia es ingeniería industrial en una reconocida universidad del país, pero tal como ocurre con mis alumnos biólogos y químicos, la programación no se les da mucho. Ella me suministró un código que ya había empezado sin embargo el mismo no hacía nada e iba a tardar más tiempo comprendiendo su tosco estilo que programando yo mi propia versión. Para que no se dieran cuenta que era “copiado”, realicé el juego sin agregar mayores características:

  • Son dos equipos, los rojos y los blancos
  • Los rojos se mueven primero
  • Para moverse se elige la coordenada de la ficha y la dirección del movimiento
  • Si un equipo falla su movimiento entonces le toca el turno al contrario
  • Solo se evita salirse del tablero al tratar de realizar un movimiento y moverse a una casilla ocupada por una ficha del mismo color
  • No se corona, la ficha llega al otro extremo y listo
  • Salen mensajes explicando el evento ocurrido al mover la ficha
  • Si es posible, una ficha se come a una de su color opuesto

Adicionalmente el código fue realizado en dos horas, probado a medias y existe algo de redundancia en las condiciones… Por favor que eso no de pie a que me consideren un mal programador… Simplemente me dio fastidio depurarlo, optimizarlo y además, debía parecer que lo hizo una persona con poca experiencia programando 😛

Archivo fuente

Para compilar y ejecutar en Linux

g++ damas.c –o damas
./damas