Primeros pasos con Xamarin, jsGFwk y Android

Android_Robot

Hace varios años atrás había tenido un contacto con Xamarin (Mono) y su set de herramientas. Especialmente para poder conseguir lo mismo que conseguía para Windows Phone: Programar aplicaciones móviles usando Visual Studio y C#.

La experiencia había sido muy positiva, aunque no había terminado de encontrar el motivo para crear una aplicación y publicarla.

Con el tiempo, HTML5 y JavaScript se hicieron más populares, y el desarrollo de video juegos fue la gran motivación para tomar estas (En especial la primera) plataformas: Así nació jsGFwk.

Pero HTML5 ha trepado tanto que hoy, en Windows Phone 8 (Y Windows 8) podemos desarrollar aplicaciones usando esta tecnología de forma nativa. Y por supuesto, también es posible hacerlo para Android, y en este caso con Xamarin.

Entonces, con esta idea en mente, me propuse hacer algunas pruebas básicas, tanto para recordar lo aprendido de Xamarin, como para probar el rendimiento de jsGFwk en Android (Y en este tipo de aplicaciones).

Dejo aquí, entonces, un pequeño paso a paso para crear aplicaciones con soporte Web para Android y, además, implementar jsGFwk para desarrollar video juegos.

image
Desde Visual Studio, creamos una nueva aplicación del tipo WebView para Android.

image

En la carpeta Assets copiamos todos los scripts de jsGFwk.

El proyecto crea, por defecto, una página HTML con directivas Razor (RazorView.cshtml). Esta será la página con la que trabajaremos. Si bien podríamos agregar nuevas vistas, no las necesitaremos para este caso.

image

En la vista, agregamos las referencias a jsGFwk y código para crear un nuevo objeto que se mueva por la pantalla.

image

En las propiedades del proyecto, es importante seleccionar la versión de API a usar, en base al dispositivo en el que haremos las pruebas.

Salvo que configuremos otras versiones, tendremos disponibles emuladores para las versiones 10, 12 y 15, pero nuestro proyecto, por defecto, estará configurado para la versión 19.

Por lo que, o deberemos configurar un emulador con soporte para esta versión, o cambiar la versión de API del proyecto.

El último paso será ejecutar el proyecto, en un dispositivo físico, o en un emulador.

image

Podremos ver cómo el objeto creado se mueve de izquierda a derecha hasta desaparecer.

Por supuesto, aún queda mucho por hacer: Eliminar la cabecera, hacer que el área de juego ocupe toda la pantalla, crear otros objetos de juego y hacer que el mismo luzca como un juego, y más.

De cualquier manera, demuestra que es posible desarrollar fácilmente con Xamarin, HTML5 y JavaScript, para Android, siendo, para el desarrollador que no esté acostumbrado a plataformas no Microsoft, sentirse como en casa.

Desarrollo de video juegos, paso a paso.

Hace un tiempo atrás habíamos iniciado con una serie de posts sobre desarrollo de video juegos con HTML5 y JavaScript. (9, 8, 7, 6, 5, 4, 3, 2, 1)

Esos posts mostraban cómo utilizar HTML5 para desarrollar video juegos, de forma artesanal, desde cero.

Con el tiempo, y con la idea de empaquetar todo eso en algo que pueda ser reutilizable, nace, jsGFwk.

jsGFwk es un Framework de desarrollo de video juegos 2D para HTML5 con JavaScript, que va evolucionando a medida de que nuevas características son requeridas.

En todo caso, para continuar con los post sobre desarrollo de video juegos y, al mismo tiempo, aprender a usar jsGFwk, nos movemos de las palabras escritas a las orales y nos hacemos videos.

A continuación, una serie de videos (Que sigue creciendo) con un paso a paso para aprender a desarrollar video juegos en 2 dimensiones con HTML5 y JavaScript.

Para ver los videos, click aquí.

Reconocimiento de voz

Con la inminente llegada de aplicaciones como Cortana, Siri y otros, donde el uso de la voz para ejecutar comandos en los dispositivos se hace cada vez más natural y al mismo tiempo, más exacta, la pregunta que surge es: ¿Cómo podemos hacer esto, nosotros, desde nuestras aplicaciones?

Si trabajamos con C# y en especial con .Net Framework 4.5, este trae un set de librerías que, trabajando en conjunto con el sistema operativo, puede emitir sonidos en base a texto escrito y al mismo tiempo, reconocer la voz y transformarla a texto.

Esta tecnología nos puede remitir a una vieja propuesta, en el caso de Microsoft mediante su TTS (Text to Speech), hoy, presentada mediante un ensamblado puramente .Net.

Importando librerías

image

El primer paso es importar el ensamblado System.Speech, el que nos proveerá los objetos necesarios para emitir sonidos o reconocer voz.

Haciendo hablar al sistema

La emisión de sonidos posee cierta simpleza. Siendo que, como decíamos, este mecanismo ya está aceitado, con un par de líneas de código podemos hacer que nuestra aplicación hable.

static void Main(string[] args)
{
            SpeechSynthesizer voice = new SpeechSynthesizer();
            while (true)
            {
                string text = Console.ReadLine();
                if (text == “quit”) { break; }
                voice.Speak(text);
            }
}

image

Aunque no podemos escucharla, la aplicación dice lo que escribamos. La voz elegida o el tipo de voz dependerá directamente de las voces que tengamos instaladas, las que podrán tener acento inglés, francés, chino o español, dependiendo de cuál seleccionemos.

Reconocer voz

El reconocimiento de voz es ligeramente diferente. Para este caso necesitaremos configurar un conjunto de palabras claves a ser analizadas, también, dependientes del idioma que estemos aceptando. Por lo que GREEN deberá, con un analizador en inglés, deberá sonar similar a GRIN para poder ser reconocido.

static void Main(string[] args)
{
    SpeechRecognizer recognizer = new SpeechRecognizer();

    Choices colors = new Choices();
    colors.Add(new string[] { “red”, “green”, “blue”, “hello”, “there” });
    GrammarBuilder grammarBuilder = new GrammarBuilder();
    grammarBuilder.Append(colors);
    Grammar grammar = new Grammar(grammarBuilder);

    recognizer.LoadGrammar(grammar);
    recognizer.SpeechRecognized += recognizer_SpeechRecognized;

    Console.ReadLine();
}

static void recognizer_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
{
    Console.WriteLine(e.Result.Text);
}

image

En resumen, podemos decir que, de cierta forma, la inteligencia de la aplicación que podamos desarrollar está relacionada con las posibles acciones asociadas a diferentes comandos de voz. Por supuesto, la calidad final de la aplicación dependerá también, en la calidad del complemento usado para reconocer la voz y transformarlo a texto.

Build 2014: Imágenes detrás de escena

Pasó el día 1 de Microsoft Build en San Francisco, con novedades centradas principalmente alrededor de la futura nueva versión de Windows Phone (Windows Phone 8.1) y el nuevo update para Windows (Windows 8.1 Update 1, ya disponible para suscriptores MSDN). Con más tiempo intentaré escribir sobre todo esto y sobre mis impresiones de la conferencia. En este post quería simplemente compartir unas pocas imágenes que muestran algunas de las cosas que suceden fuera de los keynotes y sesiones y aquellos que no tienen la suerte de poder asistir no pueden ver.

DJ musicalizando antes que empiece el Keynote

Sesiones 1:1 con expertos en diferentes tecnologías

Test de dispositivos

Stands de partners

Demo de impresoras 3D

Demo de Windows en "otros" dispositivos (IoT)

Comida

Bebida

Regalos para los asistentes

En los próximos días espero subir más (y escribir sobre lo que realmente importa :-) . Enjoy!

Desarrollo de videojuegos con HTML5–Parte 9

En los anteriores post (8, 7, 6, 5, 4, 3, 2, 1) hablamos sobre las bases del desarrollo de videojuegos con HTML5 y JavaScript. Especialmente sobre algunas técnicas de desarrollo y conceptos de programación dentro de este paradigma.

En todo caso, todo lo anterior nos sirvió para conocer el funcionamiento interno de los videojuegos, pero, como en la mayoría de los casos de desarrollo tenderá a que tengamos que escribir mucho código. La solución para este caso, usar algún framework de desarrollo que nos abstraiga de tener que escribir cada punto y coma.

Por supuesto, tenemos cientos de Frameworks. Pagos, gratuitos, open source, licenciados, etc.

Básicamente aquí dependerá de gustos ya que casi todos (Casi), tienden a contar con las mismas funcionalidades, pero con diferentes acercamientos hacia el desarrollador. Algunos tratan de tomar el control absoluto del funcionamiento del juego, otros dan mayor responsabilidad al desarrollador, y así la lista sigue.

Para la serie de ejemplos que veremos desde ahora en adelante, usaremos jsGFwk. Un Framework creado (Y aún en proceso de desarrollo) por mí, y que nace luego de varios años de experiencias en esta rama del desarrollo.

Pero sin muchos preámbulos sobre el Framework, construyamos el primer ejemplo.

El canvas

Como en todos los casos, necesitaremos de un tag <canvas> en nuestra página, el que será usando por el Framework para dibujar los diferentes elementos del juego.

<canvas id="canvas" width="640" height="480"></canvas> 

El Framework

jsGFwk está pensado para que las diferentes funcionalidades se comporten como plug-ins. Donde cada característica no sea parte de todo un paquete obligatorio a referenciar (Aunque no lo usemos), sino que solo incluyamos aquello que nos haga falta.

En este sentido, para obtener un contexto para un videojuego, solo necesitaremos agregar a la página una referencia al framework.

<script language="Javascript" src="Framework/jsGFwk.js"></script> 

De igual manera, necesitaremos especificar que lienzo deberá usar el motor del juego.


//Seteamos el ID del objeto canvas a usar

jsGFwk.settings.canvas = "canvas"; 

Creando objetos de juego

Una vez contamos con el framework, podremos crear diferentes objetos de juego. A diferencia de los ejemplos en las anteriores entregas, aquí, cada elemento del juego es un objeto que encapsulará la funcionalidad del mismo.

jsGFwk.createObject({        id: "ball",         x: 10,        y: 10,        zOrder: 2,        visible: true,        update: function(delta) {            this.x++;        },        draw: function (context) {            context.fillStyle = "rgb(255,255,255)";            context.fillRect(this.x,this.y,10,10);        }    });

La función createObject espera un objeto con algunas propiedades o funciones públicas específicas:

  • id: Representa el nombre del objeto. Este nombre es útil para acceder a propiedades de otros objetos de juego desde cualquier punto del código.
  • zOrder: Un valor que representa la profundidad del objeto. Debido a que los objetos se dibujan en capas, mientras más alto sea el valor numérico de esta propiedad, más arriba en las capas se dibujará.
  • visible: Un objeto que no cuente con la propiedad “visible” o esta esté configurada a falso, no se dibujará en la pantalla.
  • update: Por cada tick del juego, la función update se llamará una vez. Esto quiere decir que si esperamos que nuestro juego se dibuje a 24 cuadros por segundo, esta función se disparará por lo menos 24 veces por segundo. Además, recibirá un valor delta, que representa el tiempo que ha pasado entre el cuadro anterior y el cuadro actual de dibujo.
  • draw: Al igual que update, se disparará tantas veces como cuadros por segundo hayamos configurado, siempre después de que la función update haya concluido. El parámetro context, hace referencia al contexto de dibujo en el que deberemos dibujar nuestras imágenes.

Iniciando el juego

El último paso es inicializar el motor de juego.

jsGFwk.start();

Por supuesto, podemos crear objetos de juego, así como destruirlos, en cualquier momento, no es necesario que creemos todos los objetos y luego iniciemos el motor.

Como resultado, veremos que un cuadrado de color se desplaza sobre el eje X en el objeto canvas.

Untitled

En las siguientes entregas veremos más sobre este juego y cómo podemos contruir juegos de forma rápida.

Tracking de proyectos con GitHub

Existen muchas herramientas que ayudan a la gestión de proyectos de software.

Es común encontrar herramientas para el control del código fuente, reporte de horas, creación de tickets o tareas de trabajo, bugs, documentación, entre otras. Algunas más usadas, otras usadas solo por un grupo de personas dentro de un área productiva.

En todo caso, en el día a día, cuando creamos código necesitamos algunas que nos resuelvan problemas específicos, y que sin ellas, el trabajo sería difícil y lento; el control de código fuente, donde todos los desarrolladores puedan dejar su trabajo, se mantenga un historial de cambios, y que luego pueda ser usado para criterios como integración continua o verificación y validación; el control de requerimientos, bugs o características que conformen el proyecto, que nos dará visibilidad sobre el progreso del desarrollo, tareas pendientes, bugs nuevos o no resueltos, entre otros.

Por supuesto, y cómo comentaba al principio, existen cientos de herramientas para hacer esto, desde TFS, ClearCase, ClearQuest, SVN, Mercurial, SourceSafe y otros. Pero actualmente GitHub se ha transformado en un lugar común para el desarrollo, en muchos casos como repositorio de código, y por supuesto, como administrador de tareas para el proyecto.

Creando tareas

Desde el sitio Web de GitHub es posible crear diferentes “issues” que describan las tareas a realizarse para ese proyecto.

Un punto interesante en este modelo es que es posible definir una fecha esperada de cierre, la persona que se encargará de realizarla, si pertenece a un grupo de tareas más grande y que tipo de tarea es (Bug, mejora, o una que definamos por nuestra cuenta).

image GitHub nos muestra la consola de issues para el proyecto “101 Javascript Samples

Al crear una nueva tarea, es posible agregarle una descripción, imágenes y demás características que comentábamos antes.

image Un nuevo issue asignado para ser trabajado.

Una vez creado, cada issue obtendrá un número. Este número será de vital importancia a la hora de trabajar con el mismo.

image Un nuevo issue es creado y se le asigna el número 1.

Cerrando tareas

Con la lista de tareas creadas y definidas, solo necesitaremos realizar el código indicado y publicarlo.

Solo a modo de ejemplo, escribimos el siguiente código:

<script>
//Having the following object
//iterate it and execute all the functions
var o = {
    sum: function () {
        //Do math
    },
    analyze: function () {
        //Do task
    },
    task_1: function () {
        //Do task
    }}; 

//Your code here
for (var p in o) {
    console.log(p);
}</script>

El código anterior muestra cómo podemos interactuar con un objeto en Javascript tomando el nombre de sus propiedades y escribiéndolas en la consola.

Con los cambios en su sitio, solo necesitaremos publicarlos y cerrar el issue. Por supuesto, esto sería una tarea que nos consuma tiempo si por cada uno de los cambios necesitáramos ingresar al sitio Web de GitHub a marcar que tareas hemos o no cerrado. Por lo que necesitamos una forma más óptima.

image Publicamos y cerramos el issue en un solo paso.

Al momento de publicar, es posible usar los mismos comentarios para indicar que tareas estamos cerrando junto con el código.

GitHub admite una lista de palabras que, acompañadas con el número de issue, sirven para cerrar el mismo.

Por ejemplo, podríamos decir: “This resolves #200. File not found for new request”. O: “Fix #10, Fix #11 and Fix #12

En todos los casos, GitHub entenderá que queremos, con este código, declarar cerrados los issues 200, 10, 11 y 12.

La lista de palabras disponibles es la siguiente: Fix, fixes, fixed, close, closes, closed, resolve, resolves, resolved. Todas acompañadas del número de issue.

Además de ser una forma rápida de poder cerrar las tareas, una ventaja adicional es que el código quedará asociado a dicha tarea, por lo que si necesitáramos ver exactamente que código dio solución a que tarea, podremos encontrar esa información de forma muy simple.

image El código queda asociado a la tarea.

En resumen, GitHub puede resultar una herramienta que solucione, no solo, problemas con el manejo del código fuente, si no, con el conocimiento general del estado de las tareas del proyecto.

Desarrollo de videojuegos con HTML5 – Parte 8

En esta octava entrega veremos cómo interactuar con el mouse para poder mover nuestro personaje dentro del juego y dejaremos para la próxima entrega la interacción por medio del teclado.

Algo que debemos tener en cuenta es que, a diferencia de otros lenguajes o plataformas para desarrollador videojuegos, aquí estamos restringidos de forma directa por las políticas de seguridad del navegador que interpreta nuestro código. Por tal motivo, si el navegador no permitiera el uso del teclado, el mouse, o cualquier otro periférico, nosotros como desarrolladores no podríamos forzar el uso de los mismos. Diferente situación para el desarrollo nativo, ya que estos lenguajes poseen pleno acceso al dispositivo en el que se ejecutan. Con esto queremos decir que si conectáramos un joystick o algún otro dispositivo, salvo que contemos con un plugin que lea este dispositivo, no podríamos acceder al mismo de forma nativa por medio del código JavaScript.

Por otro lado, es importante entender que tanto el manejo del teclado como el manejo del mouse no son diferentes, en líneas de código, a las líneas de código que pudiéramos hacer para detectar los mismos en un front-end Web.

El mouse

El primer paso es registrar el evento para capturar las diferentes acciones del mouse. En nuestro caso, el evento Click, sobre el lienzo de dibujo. Debido a que el juego y sus acciones se realizarán sobre este, entonces será necesario capturar las acciones del mouse sobre el mismo.

canvas.addEventListener("click", mouseClick, false);

La función mouseClick se disparará cada vez que se realice un click sobre el lienzo y junto con esta llamada, una variable con las coordenadas representando el lugar donde se realizó el click.

function mouseClick(e) {
	var tx;
	var ty;

	if (e.pageX || e.pageY) {
	  tx = e.pageX;
	  ty = e.pageY;
	} else {
	  tx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
	  ty = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
	} 

	tx -= canvas.offsetLeft;
	ty -= canvas.offsetTop;

	destX = tx;
	destY = ty;
}

Las funciones pueden ser más o menos complejas, dependiendo si nuestro lienzo se encuentra dentro de otros contenedores o si posee algún estilo para modificar su posición dentro de la página Web, de cualquier manera, estos ajustes pueden ser realizados a medida que experimentemos con el funcionamiento del juego.

En el código anterior, las variables destX y destY son variables globales que contendrán las coordenadas del click del mouse, luego usaremos estas variables para interactuar con el personaje.

El personaje

Teniendo las coordenadas del click del mouse, y siguiendo con el código que hemos creado en post anteriores, usaremos estas coordenadas para que Yoda (Nuestro personaje), se mueva hacia ellas, y ya no en línea recta hasta golpear contra la caja negra. De cualquier manera, seguiremos detectando el contacto con la caja para detener su recorrido.

boxYoda.startupRectangle(x, y, 42, 39);
if (!boxYoda.intersects(boxBlock)) {
	if (x !== destX) {
		x += x < destX ? 1 : -1;
	}

	if (y !== destY) {
		y += y < destY ? 1 : -1;
	}
}

Dentro del bucle principal, en vez de simplemente incrementar la posición en el eje X, ahora realizamos un pequeño cálculo para determinar hacia donde deberá moverse el personaje. De igual forma, si el rectángulo del personaje choca con el de la caja, este cálculo se detiene y por ende, el personaje dejará de moverse.

La última modificación está en la línea que dibuja el personaje, ya que ahora deberemos incluír el eje Y.

contextBuffer.drawImage(yoda,
	walkFrame * 42, 1, 42, 39,
	x, y, 42, 39);

Como hemos podido ver, interactuar con el mouse no resulta nada complejo, solo es necesario contar con una buena rutina para detectar el punto exacto donde el mouse es presionado.

Insertar valores explícitamente en una columna IDENTITY

Alguna vez puede que nos encontraremos con la situación de querer migrar datos de una base de datos a otra. Y Cuando sucede es muy probable que columnas con la propiedad IDENTITY nos traigan un dolor de cabeza ya que los valores auto generados en el origen pueden diferir de los datos en la base destino.

¿Entonces como hacemos para insertar nuestros nuevos valores en el destino? Pues bien, una forma de resolver esto es “apagando” la restricción impuesta por el IDENTITY. Cosa que en realidad es muy sencillo.
Supongamos por un momento que disponemos una tabla “Ciudad” cuyos campos son “Id” y “Nombre”. Donde “Id” es la Primary Key definida con la propiedad IDENTITY. Supongamos también que ya tenemos varias ciudades insertadas cuyo máximo id es 7 y ahora queremos insertar los siguientes datos:

INSERT INTO [Ciudad] (Id,Nombre)
VALUES (9,'Posadas')

INSERT INTO [Ciudad] (Id,Nombre)
VALUES (11,'Claromeco')

INSERT INTO [Ciudad] (Id,Nombre)
VALUES (13,'Bariloche')

Normalmente esto fallaría por varias razones (sin contar que no se puede insertar valores en forma explicita en la columna Id). Si nos fijamos queremos insertar ciudades cuyos id no son ni consecutivos con el ultimo que tenemos almacenado ni entre ellos mismos. Para poder salvar estos problema entonces haremos lo siguiente:

SET IDENTITY_INSERT Ciudad ON

INSERT INTO [Ciudad] (Id,Nombre)
VALUES (9,'Posadas')

INSERT INTO [Ciudad] (Id,Nombre)
VALUES (11,'Claromeco')

INSERT INTO [Ciudad] (Id,Nombre)
VALUES (13,'Bariloche')

SET IDENTITY_INSERT Ciudad OFF

La diferencia esta en las sentencias “SET IDENTITY_INSERT Ciudad ON” y en “SET IDENTITY_INSERT Ciudad OFF”. La primer sentencia se encarga de deshabilitar temporalmente la restricción de no poder insertar valores explícitamente en la tabla Ciudad. La segunda se encarga de volver a habilitar la inserción de valores autogenerados.

Luego de ejecutar la sentencia “SET IDENTITY_INSERT Ciudad OFF” el próximo valor de la columna Id corresponderá al siguiente del mayor insertado, en nuestro caso 14.

Advertencia

Si ya existe una tabla con esta propiedad establecida en ON y se ejecuta una instrucción SET IDENTITY_INSERT ON para otra tabla, SQL Server devuelve un mensaje de error que indica que SET IDENTITY_INSERT ya está establecido en ON y la tabla para la que se ha establecido.

 

Saludos!

Obtener un valor de una fila recién insertada

Es muy común trabajar con tablas en las bases de datos cuya Primary Key fueron creadas con la propiedad IDENTITY para que su valor sea autoincrementable. Entonces cuando hacemos inserts sobre dicha tabla, en principio, no tenemos forma de saber el valor de dicho campo.

Supongamos por un momento que tenemos una tabla “Ciudad” cuyos campos son “Id” y “Nombre”. Donde “Id” es la Primary Key definida con la propiedad IDENTITY. Supongamos ahora que necesitamos ejecutar una sentencia para insertar una “Ciudad” en la tabla y queremos saber con que Id se inserto.

Una forma sencilla de hacer esto, es la siguiente:

INSERT INTO Ciudad
OUTPUT  Inserted.Id
SELECT 'Nombre'

Donde Inserted es una tabla temporal especial que Sql Server administra y nos permite ver los valores de todas las columnas que acabamos de insertar.

Saludos!

Cuando un padre y su hijo no logran comunicarse

Buenas!

Antes que nada, voy a hacer una aclaración necesaria: no! no es un artículo de relaciones familiares, ni de psicología ni mucho menos… Me refiero a la problemática de lograr que un iframe pueda enviar y recibir mensajes de la ventana padre que lo contiene (incluso pudiendo ser de dominios distintos).

Cuándo a un desprevenido del tema como yo le toca lidiar con esto, algo que suena fácil y que parece no tener más complicaciones que incluir el correspondiente javascript que haga referencia al elemento hijo desde el padre o al padre desde el hijo, según sea el caso, termina siendo un dolor de cabeza. Entonces uno empieza a investigar y se encuentra con varios conceptos que hasta el momento ignoraba, como CORS (Cross-Origin Resource Sharing), same origin policy, etc.. Y lo siguiente que uno piensa es: “ok, es lógico que esto funcione así, sería muy inseguro que, por ejemplo, yo pudiera hacer una página con un iframe a gmail.com y que cuando un usuario ingrese sus datos yo pudiera escuchar en mi ventanita el evento keypress y robarme sus datos!”

No voy a desarrollar los conceptos que mencioné porque hay gente que ya lo hace mucho más claro. Acá dejo algunos links que a mi me sirvieron como para empezar a “empaparme” del tema:
http://en.wikipedia.org/wiki/Cross-origin_resource_sharing
http://en.wikipedia.org/wiki/Same_origin_policy
http://softwareas.com/cross-domain-communication-with-iframes

Lo bueno es que hay algunos mecanismos para relajar estas políticas de seguridad, empezando por el caso más simple en que el dominio/origen es el mismo hasta llegar al caso complejo en que son dos scripts de distintas ventanas y de distintos dominios.

Yo necesitaba algo que me salve para el caso complejo. Para ser más específico, necesitaba que mi iframe pueda avisarle a la ventana que lo contiene sobre cierto evento. Y la respuesta era PostMessage. Esta herramienta provee una forma de enviar mensajes de manera muy simple y también segura. Acá va el código:

Receptor:

var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
var eventer = window[eventMethod];
var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";

eventer(messageEvent, function (e) {
    alert('Recibí el mensaje ' + e.data);
}, false);

El código para manejar el evento considera el distinto mecanismo del que hace uso el IExplorer.

Emisor:

parent.postMessage(un_mensaje_cualquiera, la_url_del_emisor);

Esta es la versión más simple y reducida. Se puede, por ejemplo:
- Consultar el origen (window o iframe) del emisor del mensaje mediante e.source
- Consultar la URL del emisor del mensaje mediante e.origin (y filtrar si es de un desconocido)
- Consultar el mensaje en sí con e.data

Quedando algo así:

window.addEventListener('message', function(event) {
if(event.origin !== 'http://blogs.kinetica-solutions.com') return;
    console.log('message received: ' + event.data, event);
    event.source.postMessage('Aca te respondo!', event.origin);
},false);

También se puede agregar en el emisor el mismo manejo de eventos que el receptor y permitirle así recibir mensajes de respuesta, tal como el que está mandando el del ejemplo de arriba.

Todo era risas hasta que la letra chica decía que esto funciona en HTML5… Y yo estaba trabajando con un navegador precario que no soportaba esta funcionalidad!

Lo que me terminó salvando es un hack muy piola: cuando cambias el fragmento identificador de una URL (que es el que viene despues del “#”), la página no se recarga y si combinamos esto con qué el location del parent es una propiedad a la que sí puede acceder el iframe hijo entonces… Bingo! Tenemos un lugar donde podemos dejar mensajes.

La contra de ésto es que vamos a necesitar un mecanismo para consultar periódicamente si hay un nuevo mensaje (el conocido setInterval es el candidato número 1) lo cuál representa un costo en performance, pero es un costo a pagar más que aceptable si el navegador no te da una mano.

Espero que les haya parecido interesante. Mi intención no era explicar todo el marco teórico sino simplemente contarles las soluciones prácticas que manejé ante un problema concreto y que si les pica la curiosidad puedan arrancar a investigar desde donde yo lo hice.

Saludos!