Tag Archives: código

Tutorial Avanzado de Titanium – Bonjour Networking

Titanium Appceletaror Mobile ha implementado el protocolo de redes Bonjour para iOs (o ZeroConf si lo prefieres) que te permite conectarte a otro dispositivo que se encuentre en la misma red.

Antes de comenzar con la parte aburrida – quiero decir código – veamos un vídeo con una pequeña demostración que nos muestra a 3 dispositivos jugando juntos 🙂

Trabajando en Redes con Titanium Mobile en iOs

Me gustaría mencionar que el iPod es de segunda generación – por lo tanto menos capaz (los retrasos son visibles en el vídeo) y de alguna manera, algunas veces parece perder paquetes. Probé la misma aplicación con un iPad en vez de un iPod y todo funcionó bien.

Bonjour

Basandome en el código que se consigue en KitchenSink he creado una pequeña función que crea la conexión por nosotros y nos retorna un objeto que te permite iniciarlo, cerrarlo y escribir en el socket.

Bonjour es un poco extraño para entender por aquellos con menos experiencia pero en resumen, la cosa es así:

  • Necesitamos un socket en modo lectura-escritura que será usado por localService para publicar su presencia.
  • Cada localService tiene que tener su propio y único nombre para poder identificarse en la red.

Aparte de esto, necesitamos un serviceBrowser para encontrar a los demás dispositivos alrededor (que hayan publicado su presencia por supuesto).

Como todo funciona asíncronamente, tendremos que confiar en los eventos para capturar los datos enviados por alguien o los cambios en el número de dispositivos conectados.

El serviceBrowser tiene el evento updatedServices donde podemos capturar los servicios publicados. En esta función intentaremos capturar el evento de lectura de cada servicio que es el que nos dice qué datos son enviados por la red.

Advertencia: Cierra la conexión de red en el momento en que no la necesites más.

La Función de Conexión de Red

La función que he creado se encarga de esto, de manera que tu solo tienes que usarla como se encuentra el ejemplo debajo:

Titanium.include('bj.js');
 
var connection = bjnet('my_unique_name', function(data){
	var json_data = JSON.parse(data);
	//do something with this data;
});
 
connection.start();

En otro punto de tu app, donde quieras enviar el mensaje, solo tienes que hacer esto:

	connection.write('my_message');

Como dije antes, no olvides limpiar todo:

win.addEventListener('close', function(e) {
	connection.stop();
});

Que sucede en el demo?

El ejemplo en el video es bastante sencillo. Dependiendo de que bola toques (roja, verde o azul) creas una nueva conexión con ese nombre y la inicias. En este momento cualquier mensaje proveniente de la red es parseado en JSON y una pequeña bola es creada con las coordenadas y color específico.

En tu turno, cuando tocas la pantalla, envías tus coordenadas y color por la red para que los demás dispositivos sepan que dibujar. Cada mensaje es un Objeto JSON expreso en texto como el que sigue:

	{coords:{x:100,y:200},player:{name:'red', color:'#f00'}}

Como nota adicional, el demo usa cero imágenes. Ninguna. Todo es nativo y planeo un futuro tutorial sobre cómo hacer esto. 🙂

El código

El código está en Github Github y puedes descargarlo desde aquí.

Todo se encuentra bajo licencia MIT pero me gustaría escuchar lo que tengan que decir.

Cómo leen los lectores de pantalla una página con HTML5 y ARIA

Despues de ver cómo AT lee un contenido generado con pseudo-elementos CSS estaba pensando en pasar a HTML5. Y como hay muchas personas diciendo que deberíamos mezclar HTML5 con ARIA para incrementar la accesibilidad de un sitio web, entonces, ¿por qué no probar y ver lo que pasa?

Un poco de código…

...
 
<header id="header" role="banner">  
    <div id="logo">Logo</div>
    <nav role="navigation">
        <ul id="mainnav">........</ul>
    </nav>
</header>
 
<section id="content" role="main">  
 
    <h1>A level one heading here please</h1>
 
    <div role="application"><p>Here is where an application will be coded. </p></div> 
 
    <article role="article">             
            <h2 class="index-headings">Blog entry no 1</h2>
            <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit...</p>
    </article>
 
    <article role="article">
            <h2 class="index-headings">Blog entry no 2</h2>
            <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit...</p>
    </article>
 
</section> 
 
<aside role="complementary">  
    <h2>Sidebar</h2>
    <ul>......................</ul>
</aside>
 
<footer id="footer"  role="contentinfo">This is where the footer will stay.</footer>     
...

Esta es la página con ambos elementos HTML5:

  • header
  • nav
  • section
  • article
  • aside
  • footer

y los roles ARIA (aprende más sobre ARIA):

  • role=”banner” – para el elemento header
  • role=”navigation” – para el elemento nav
  • role=”main” – anexo a section
  • role=”application” – en caso de que necesite añadir un widget
  • role=”article” – para el elemento article
  • role=”complementary” – para aside
  • role=”contentinfo” – para footer

Cómo NVDA, JAWS y Windoes Eyes leyeron la versión con sólo HTML5

Para hacer la historia corta, ningún lector de pantalla notó los elementos HTML5 – como se esperaba. Todos se comportaron como si esos elementos fuesen simples DIVs y leyeron la página web de acuerdo a esto.

Cómo NVDA, JAWS y Windoes Eyes leyeron la versión HTML5 + ARIA

Mucho mejor esta vez, ARIA está haciendo maravillas aunque no entiendo por qué Windows Eyes ni siquiera pronuncia la existencia de estos encabezados… Soy un novato en este campo así que, ¿tal vez hice algo malo? No quiero cometer una injusticia con WE así que digamos que los resultados fueron inconclusos en relación con este software.

La Diferencia

Así que cuál era la diferencia entre las dos versiones? Qué aportó ARIA desde este punto de vista?

El área del banner: role=”banner”

NVDA – “banner landmark logo here navigation landmark list with 4 items visited link home……. ”
JAWS – “banner landmark logo here navigation landmark list with 4 items visited link home……. ” Al principio también dijo que habían 8 marcas, muy bien!!!

El área principal: role=”main”

NVDA – “main landmark heading level one …”
JAWS – “main landmark heading level one …”

El área de aplicación: role=”application”

NVDA – no se leyó el rol de aplicación.
JAWS – “application landmark here is where….”

Los Artículos: role =”article”

NVDA – el artículo no fue mencionado en lo absoluto.
JAWS – “article landmark heading level….”

La Barra lateral: role=”complementary”

NVDA la barra lateral fue leída de esta manera: “complementary landmark heading level 2…..”
JAWS – “complementary landmark heading level 2…..”

El pié: role=”contentinfo”

– y el pie de pagina: “content info landmark this is where the….”
JAWS – “content info landmark this is where the….”

Hasta ahora JAWS fue el único capaz de leer todas las marcas mientras que NVDA falló en el artículo y la aplicación. Como mencioné antes, Windows Eyes no leyó los elementos ARIA pero tal vez soy sólo yo siendo un novato… Aprecio mucho tu opinión, quizás juntos podamos hacer que funcione. 🙂

Probando la accesibilidad del contenido generado por CSS

Este artículo es acerca de cómo los lectores de pantalla leen el contenido añadido con pseudo elementos CSS :before y :after (en CSS3 son ::before y ::after).

Estoy tratando de aprender a usar tecnología asistiva cuando desarrollo sitios web y recientemente vi como no importa cuanto W3C quiera que usemos ciertos elementos CSS, siempre habrá desarrolladores/diseñadores quienes intentarán probar los límites de las especificaciones.

Mientras que te aconsejo que NO uses pseudo elementos para generar contenido útil (limitate a generar citas o elementos de diseño), sólo en caso de que alguien piense que lo estupendo resida en generar contenido con CSS porque todo lo demás ya es viejo, veamos cómo las personas que usan los lectores de pantalla se “beneficiarán” de la idea.
Continue reading

Crear un temporizador regresivo con Titanium Appcelerator

En este post trataremos de mostrarle cómo hacer un temporizador regresivo usando Titanium Appcelerator para su aplicación en Iphone o Android.

Primero crearemos un objeto OOP countDown que puede ser usado independientemente en segundo plano en la aplicación, el cual, conectaremos con algunos elementos de interface.

El Objeto countDown

Para tener funcional el temporizador regresivo, necesitaremos declarar algunas propiedades y algunos métodos.

Como propiedades colocaremos :

time:{ m : minutes, s : seconds },
total_seconds : m*60+s

Creo que es bastante claro, “time” es un objeto con minutos y segundos y segundos_totales (total_seconds) contiene el número de segundos hasta que alcancemos 00:00

Necesitaremos colocar métodos que nos permitan:

  • Ajustar un tiempo en forma de contador.
  • Parar el temporizador.
  • Iniciarlo.

Además necesitamos colocar algunas funciones de llamadas que serán ejecutadas en cada tick del temporizador – fn_tick – y una que se ejecutará cuando el temporizador alcance 00:00 denominada fn_end.

No haremos una llamada para el inicio porque sabemos cuando ocurre esto y podemos lanzarlo por nosotros mismos.

El temporizador countDown se verá como esto:

var my_timer = new countDown( minutes, seconds, fn_tick, fn_complete);

Y seremos capaces de aplicar:

my_timer.set( minutes, seconds );
my_timer.start();
my_tmer.stop();

Debajo se encuentra el código que define el countDown (bastante simple).

var countDown =  function( m , s, fn_tick, fn_end  ) {
	return {
		total_sec:m*60+s,
		timer:this.timer,
		set: function(m,s) {
			this.total_sec = parseInt(m)*60+parseInt(s);
			this.time = {m:m,s:s};
			return this;
		},
		start: function() {
			var self = this;
			this.timer = setInterval( function() {
				if (self.total_sec) {
					self.total_sec--;
					self.time = { m : parseInt(self.total_sec/60), s: (self.total_sec%60) };
					fn_tick();
				}
				else {
					self.stop();
					fn_end();
				}
				}, 1000 );
			return this;
		},
		stop: function() {
			clearInterval(this.timer)
			this.time = {m:0,s:0};
			this.total_sec = 0;
			return this;
		}
	}
}

Y ahora, para usarlo en nuestro código, haremos algo como esto:

var my_timer = new countDown(1 , 5 ,
	function()	{
		//something here...
	},
	function() {
		// something here...
	}
);
 
my_timer.start();

Ok, el ejemplo de arriba es inútil, necesitaremos mostrar el tiempo actual en cada tick del contador (osea, en cada segundo) y al final, tendremos una alerta al usuario cuando se alcance 00:00

Adicionalmente, necesitaremos algunos elementos de interface para acceder a los métodos del contador para mostrar el tiempo actual.

Para esto, crearemos una etiqueta llamada display_lbl, que mostrará el tiempo y además 3 botones: set_btn, start_btn y stop_btn.

Crear el código es bastante simple, así que no les pondré el código aquí, pero puede echarle un vistazo cuando bajen el proyecto del temporizador regresivo.

Lo que es mas importante es conectar la interface con el contador del temporizador.

Así que creamos el temporizador y le colocamos las funciones fn_tick y fn_end

var my_timer = new countDown(5,30, 
		function() {
			display_lbl.text = my_timer.time.m+" : "+my_timer.time.s;
		},
		function() {
			alert("The time is up!");
		}
	);

Y asi es como conectaremos los botones con my_timer

 
set_btn.addEventListener('click',function(){
	display_lbl.text = "5 : 30";
	my_timer.set(5,30);
});
 
stop_btn.addEventListener('click',function(){
	my_timer.stop();
});
 
start_btn.addEventListener('click',function(){
	my_timer.start();
});

Como puede ver, también le colocamos a la etiqueta un valor inicial cuando iniciamos el temporizador porque de otra manera, perderemos el primer segundo. Hacemos esto aquí para mantener el objeto del temporizador libre de interacción externa y de esta manera podremos usarlo incluso sin interface.

Así es como se verá el proyecto final:

Countdown timer with Appcelerator

Por favor, tenga en mente que este es solo un ejemplo simple y no tenemos mecanismos de control para detectar cuando el usuario para el temporizador o cuando alcance 00:00 por sí mismo – pero se lo pueden añadir como ejercicio.

Pueden bajar el directorio de Recursos desde aquí.

Todo lo demás tiene licencia MIT y puede usarlo en cualquier aplicación que quiera, no obstante, si difunde la palabra sería agradable.