<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>.:: klr20mg ::. Una dosis diaria de .... &#187; Flex 4</title>
	<atom:link href="http://klr20mg.com/category/flex-4/feed/" rel="self" type="application/rss+xml" />
	<link>http://klr20mg.com</link>
	<description>Blog acerca de desarrollo orientado hacia Flash, Flex y Actionscript.</description>
	<lastBuildDate>Wed, 26 May 2010 21:59:38 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Air 2.0 Conexi&#243;n IMAP mediante SecureSocket</title>
		<link>http://klr20mg.com/2010/02/26/air-2-0-conexin-imap-mediante-securesocket/</link>
		<comments>http://klr20mg.com/2010/02/26/air-2-0-conexin-imap-mediante-securesocket/#comments</comments>
		<pubDate>Sat, 27 Feb 2010 01:56:24 +0000</pubDate>
		<dc:creator>Tmeister</dc:creator>
				<category><![CDATA[AS3]]></category>
		<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Adobe AIR]]></category>
		<category><![CDATA[Ejemplos]]></category>
		<category><![CDATA[Flex 4]]></category>
		<category><![CDATA[AIR 2.0]]></category>
		<category><![CDATA[FlashBuilder]]></category>

		<guid isPermaLink="false">http://klr20mg.com/?p=546</guid>
		<description><![CDATA[Una de las nuevas características de Adobe Air 2.0 es la conexión a servidores mediante sockets encriptados (SSL). Uno de los servicios mas comunes que utiliza una conexión encriptado son los proveedores de correo usando IMAP. Para este ejemplo vamos a conectarnos al servidor IMAP de Gmail y obtener el numero de mensajes nuevos y [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://klr20mg.com/wp-content/uploads/2010/02/Adobe_Air-logo-8BE840B3A1.gif" alt="" title="Adobe_Air-logo-8BE840B3A1" width="200" height="200" class="alignright size-full wp-image-548" /><br />
Una de las nuevas características de Adobe Air 2.0 es la conexión a servidores mediante sockets encriptados (SSL).</p>
<p>Uno de los servicios mas comunes que utiliza una conexión encriptado son los proveedores de correo usando IMAP.</p>
<p>Para este ejemplo vamos a conectarnos al servidor IMAP de Gmail y obtener el numero de mensajes nuevos y mensajes en total que existen en nuestra cuenta.</p>
<p>Para fines prácticos de este ejemplo necesitamos:</p>
<ul>
<li>Una cuenta de Gmail, <a href="http://mail.google.com/mail/#settings/fwdandpop">con IMAP habilitado</a></li>
<li><a href="http://labs.adobe.com/technologies/flashbuilder4/">FlashBuilder</a></li>
<li><a href="http://labs.adobe.com/technologies/air2/">Adobe AIR 2.0</a></li>
</ul>
<p><span style="font-family: Georgia;">Lo primero es crear una interfaz sencilla en donde se pueda insertar el nombre de usuario, la contraseña, campos de output y un boton para iniciar el proceso.</span></p>
<pre class="brush: xml; light: true;">
	&lt;s:Label x=&quot;10&quot; y=&quot;17&quot; text=&quot;Gmail username:&quot;/&gt;
	&lt;s:Label x=&quot;10&quot; y=&quot;45&quot; text=&quot;Gmail password:&quot;/&gt;
	&lt;s:TextInput y=&quot;10&quot; id=&quot;username_txt&quot; change=&quot;_username = username_txt.text&quot; right=&quot;10&quot; left=&quot;120&quot;/&gt;
	&lt;s:TextInput y=&quot;40&quot; id=&quot;password_txt&quot; change=&quot;_password = password_txt.text&quot; displayAsPassword=&quot;true&quot; right=&quot;10&quot; left=&quot;120&quot;/&gt;
	&lt;s:Button y=&quot;70&quot; label=&quot;Tell me!!&quot; click=&quot;start()&quot; right=&quot;10&quot;/&gt;
	&lt;s:Label x=&quot;10&quot; y=&quot;100&quot; width=&quot;280&quot; id=&quot;result_txt&quot;/&gt;
	&lt;s:TextArea id=&quot;out_txt&quot; editable=&quot;false&quot; right=&quot;10&quot; bottom=&quot;10&quot; top=&quot;130&quot; left=&quot;10&quot;/&gt;
</pre>
<p><span id="more-546"></span></p>
<p>El resultado de esto se ve de esta forma:</p>
<div align="center">
<img src="http://klr20mg.com/wp-content/uploads/2010/02/gmailSSL.png" alt="" title="gmailSSL" width="308" height="280" class="aligncenter size-full wp-image-547" />
</div>
<p>Despues de tener nuestra interfaz vamos a declarar todas la variables y constantes que vamos a necesitar:</p>
<pre class="brush: as3; light: true;">
			/******************************************************************
			 *	Datos de la cuenta (Gmail IMAP)
			 * ***************************************************************/

			private static const INCOMING_SERVER:String = &quot;imap.gmail.com&quot;;
			private static const PORT:int = 993;
			private var _username:String = &quot;&quot;;
			private var _password:String = &quot;&quot;;

			/******************************************************************
			 * Socket &amp;&amp; Stuff
			 * ***************************************************************/ 

			private var _server:Socket;
			private var _buffer:ByteArray;
			private var _action:String;
			private var _totalMessages:String;
			private var _newMessages:String;

			/******************************************************************
			 * Respuestas del servidor (para filtar el contenido)
			 * http://tools.ietf.org/html/draft-gahrns-imap-namespace-00
			 * ****************************************************************/

			private static const CONNECT:String = &quot;*&quot;;
			private static const LOGIN:String = &quot;A002&quot;;
			private static const STATUS:String = &quot;A006&quot;;
			private static const CRLF:String = &quot;\r\n&quot;;
			private var _regSearch:RegExp = RegExp(&quot;\\&quot;+_action+&quot;\\r\\n&quot;);
</pre>
<p>Aqui hay un par de cosas que debo resaltar:</p>
<pre class="brush: as3; light: true;">
			private var _buffer:ByteArray;
</pre>
<p>En esta variable almacenaremos las respuestas que nos envié el servidor.</p>
<pre class="brush: as3; light: true;">
			private var _regSearch:RegExp = RegExp(&quot;\\&quot;+_action+&quot;\\r\\n&quot;);
</pre>
<p>Con esta expresion regular verificaremos si el mensaje que recibimos del servidor es util para nosotros.</p>
<pre class="brush: as3; light: true;">
			private static const CONNECT:String = &quot;*&quot;;
			private static const LOGIN:String = &quot;A002&quot;;
			private static const STATUS:String = &quot;A006&quot;;
</pre>
<p>Estas constantes son los identificadores de los mensajes que se mandan desde y hacia el servidor para saber mas de estos identificadores recomiendo esta lectura <a href="http://tools.ietf.org/html/draft-gahrns-imap-namespace-00">http://tools.ietf.org/html/draft-gahrns-imap-namespace-00</a></p>
<p>Ahora nos queda inicializar nuestro socket y crear los eventos que usaremos para comunicarnos con el servidor</p>
<pre class="brush: as3; light: true;">
				_server = new SecureSocket();
				_server.addEventListener(Event.CONNECT, onConnect);
				_server.addEventListener(Event.CLOSE, onClose);
				_server.addEventListener(ProgressEvent.SOCKET_DATA, onData);
				_server.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
</pre>
<p>El único cambio con respecto a trabajar con Sockets sin encriptar es el constructor de la clase en lugar de usar </p>
<pre class="brush: as3; light: true;">
				_server = new Socket();
</pre>
<p>Ahora debemos utilizar</p>
<pre class="brush: as3; light: true;">
				_server = new SecureSocket();
</pre>
<p>Así de simple; Bien, hemos seteado los listeners para CONNECT, SOCKET_DATA, CLOSE y IO_ERROR vamos a concentranos solamente en SOCKET_DATA que es el evento que se dispara al momento de recibir un mensaje del servidor.</p>
<pre class="brush: as3; light: true;">
			private function onData(e:ProgressEvent):void
			{
				out_txt.text += &quot;Data &quot; + e+&quot;\n&quot;;
				var socket:Socket = e.target as Socket;
				var bufferString:String;
				socket.readBytes(_buffer, _buffer.length, socket.bytesAvailable);
				bufferString = _buffer.toString();
				out_txt.text += &quot;SERVER: &quot; + _buffer.toString()+&quot;\n&quot;;
				if (  bufferString.search( _regSearch ) )
				{
					out_txt.text += &quot;Es una respuesta valida parsea\n&quot;;
					parseResponse();
				}
				cursorManager.removeBusyCursor()
			}
</pre>
<p>En esta función recibimos el evento y tomamos el contenido del mensaje mediante el método readBytes y lo almacenamos en la variable _buffer</p>
<pre class="brush: as3; light: true;">
				socket.readBytes(_buffer, _buffer.length, socket.bytesAvailable);
</pre>
<p>Verificamos que el mensaje corresponda a nuestra petición, en este caso solo usamos 3 peticiones CONNECT, LOGIN, STATUS y si el mensaje es correcto parseamos el contenido.</p>
<p>El primer mensaje que recibimos del servidor es el de conexión</p>
<p><strong>SERVER: * OK Gimap ready for requests from 189.216.40.184 14if7528374pzk.62</strong></p>
<p>Una vez que estemos conectados mandamos nuestras credenciales para que el servidor nos autentique y cambiamos el mensaje a LOGIN indicando que estamos esperando el mensaje de respuesta de la solicitud de logueo.</p>
<pre class="brush: as3; light: true;">
				if ( _action == CONNECT )
				{
					out_txt.text += &quot;Es es tag de conexion manda login\n&quot;;
					_server.writeUTFBytes(LOGIN + &quot; LOGIN &quot; + _username + &quot; &quot; + _password + CRLF);
					_action = LOGIN;
					_server.flush();
					return;
				}
</pre>
<p>Se envia el mensaje y de inmediato recibimos la respuesta del servidor, en caso de login correcto:</p>
<p><strong>A002 OK tmeister@gmail.com authenticated (Success)</strong></p>
<p>Si es incorrecto:</p>
<p><strong>A002 NO [ALERT] Invalid credentials (Failure)</strong></p>
<p>Con esto es muy fácil saber el resultado de la operación, usemos indexOf para saber si la palabra &#8220;OK&#8221; existe</p>
<pre class="brush: as3; light: true;">
				if ( _action == LOGIN )
				{
					out_txt.text += &quot;Es la respuesta del login\n&quot;;
					if( bufferString.indexOf(&quot;OK&quot;) != -1 )
					{
						out_txt.text += &quot;El login es correcto, estamos autenticados - Pedir correos sin leer\n&quot;;
						_action = STATUS;
						_server.writeUTFBytes(STATUS + &quot; STATUS inbox (MESSAGES UNSEEN)&quot; + CRLF);
						_server.flush();
					}else
					{
						out_txt.text += &quot;Ooops!! Las credenciales no son validas.\n&quot;;
						Alert.show(&quot;Ooops!! Las credenciales no son validas.&quot;, &quot;Error&quot;);
						_server.close();
					}
					return;
				}
</pre>
<p>Excelente estamos autenticados, Ahora que? solo nos falta pedir el estatus de la cuenta pidiendo los mensajes totales y los mensajes nuevos de la carpeta Inbox</p>
<pre class="brush: as3; light: true;">
						_server.writeUTFBytes(STATUS + &quot; STATUS inbox (MESSAGES UNSEEN)&quot; + CRLF);
</pre>
<p>El ultimo paso es recibir el mensaje del servidor con la información que pedimos y parsearla, al ser texto solo tenemos que usar indexOf y substring para acceder a lo que nos interesa</p>
<p><strong>STATUS &#8220;inbox&#8221; (MESSAGES 61298 UNSEEN 5)</strong></p>
<pre class="brush: as3; light: true;">
				if( _action == STATUS )
				{
					out_txt.text += &quot;Es la respuesta del Status &quot; + bufferString+&quot;\n&quot;;
					var startSub:int = bufferString.indexOf(&quot;(&quot;);
					var endSub:int = bufferString.indexOf(&quot;)&quot;);
					var message:String = bufferString.substring(startSub+1, endSub);
					var slides:Array = message.split(&quot; &quot;);
					var count:int = 0;
					for each( var slide:String in slides )
					{
						switch( slide )
						{
							case &quot;MESSAGES&quot;:
								_totalMessages = slides[count + 1];
								break;
							case &quot;UNSEEN&quot;:
								_newMessages = slides[count + 1];
								break;
						}
						count++;
					}
					result_txt.text = _newMessages + &quot; mensajes nuevos, de &quot; + _totalMessages + &quot; en total&quot;;
					out_txt.text += _totalMessages;
					out_txt.text += _newMessages;
					_action = null;
					_server.close();
				}
			}
</pre>
<p>Sin duda, lo mas complejo al momento de trabajar con Sockets es saber utilizar e implementar el protocolo de comunicación pero esa ya es otra historia.</p>
<p>Por ultimo les dejo el código completo</p>
<pre class="brush: as3;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;s:WindowedApplication xmlns:fx=&quot;http://ns.adobe.com/mxml/2009&quot;
					   xmlns:s=&quot;library://ns.adobe.com/flex/spark&quot;
					   xmlns:mx=&quot;library://ns.adobe.com/flex/halo&quot;
					   creationComplete=&quot;init(event)&quot;
					    width=&quot;300&quot; height=&quot;250&quot;&gt;
	&lt;fx:Script&gt;
		&lt;![CDATA[
			import flash.events.Event;
			import flash.events.IOErrorEvent;
			import flash.events.MouseEvent;
			import flash.events.ProgressEvent;
			import flash.net.SecureSocket;
			import flash.net.Socket;
			import flash.utils.ByteArray;

			import mx.controls.Alert;
			import mx.events.FlexEvent;

			private static const INCOMING_SERVER:String = &quot;imap.gmail.com&quot;;
			private static const PORT:int = 993;
			private var _username:String = &quot;&quot;;
			private var _password:String = &quot;&quot;;

			private var _server:Socket;
			private var _buffer:ByteArray;
			private var _action:String;
			private var _totalMessages:String;
			private var _newMessages:String;

			private static const CONNECT:String = &quot;*&quot;;
			private static const LOGIN:String = &quot;A002&quot;;
			private static const STATUS:String = &quot;A006&quot;;
			private static const CRLF:String = &quot;\r\n&quot;;
			private var _regSearch:RegExp = RegExp(&quot;\\&quot;+_action+&quot;\\r\\n&quot;);

			protected function init(event:FlexEvent):void
			{

				_server = new SecureSocket();
				_server.addEventListener(Event.CONNECT, onConnect);
				_server.addEventListener(Event.CLOSE, onClose);
				_server.addEventListener(ProgressEvent.SOCKET_DATA, onData);
				_server.addEventListener(IOErrorEvent.IO_ERROR, onIOError);

				_buffer = new ByteArray()
			}
			private function onConnect(e:Event):void
			{
				out_txt.text += &quot;Conexion establecida &quot; + e.toString()+&quot;\n&quot;;
			}
			private function onClose(e:Event):void
			{
				out_txt.text += &quot;Conexion cerrada &quot; + e+&quot;\n&quot;;
			}
			private function onData(e:ProgressEvent):void
			{
				out_txt.text += &quot;Data &quot; + e+&quot;\n&quot;;
				var socket:Socket = e.target as Socket;
				var bufferString:String;
				socket.readBytes(_buffer, _buffer.length, socket.bytesAvailable);
				bufferString = _buffer.toString();
				out_txt.text += &quot;SERVER: &quot; + _buffer.toString()+&quot;\n&quot;;
				if (  bufferString.search( _regSearch ) )
				{
					out_txt.text += &quot;Es una respuesta valida parsea\n&quot;;
					parseResponse();
				}
				cursorManager.removeBusyCursor()
			}
			private function onIOError(e:IOErrorEvent):void
			{
				out_txt.text += &quot;IOError &quot; + e+&quot;\n&quot;;
			}

			private function parseResponse():void
			{
				var bufferString:String = _buffer.toString();
				_buffer.clear();
				if ( _action == CONNECT )
				{
					out_txt.text += &quot;Es es tag de conexion manda login\n&quot;;
					_server.writeUTFBytes(LOGIN + &quot; LOGIN &quot; + _username + &quot; &quot; + _password + CRLF);
					_action = LOGIN;
					_server.flush();
					return;
				}
				if ( _action == LOGIN )
				{
					out_txt.text += &quot;Es la respuesta del login\n&quot;;
					if( bufferString.indexOf(&quot;OK&quot;) != -1 )
					{
						out_txt.text += &quot;El login es correcto, estamos autenticados - Pedir correos sin leer\n&quot;;
						_action = STATUS;
						_server.writeUTFBytes(STATUS + &quot; STATUS inbox (MESSAGES UNSEEN)&quot; + CRLF);
						_server.flush();
					}else
					{
						out_txt.text += &quot;Ooops!! Las credenciales no son validas.\n&quot;;
						Alert.show(&quot;Ooops!! Las credenciales no son validas.&quot;, &quot;Error&quot;);
						_server.close();
					}
					return;
				}
				if( _action == STATUS )
				{
					out_txt.text += &quot;Es la respuesta del Status &quot; + bufferString+&quot;\n&quot;;
					var startSub:int = bufferString.indexOf(&quot;(&quot;);
					var endSub:int = bufferString.indexOf(&quot;)&quot;);
					var message:String = bufferString.substring(startSub+1, endSub);
					var slides:Array = message.split(&quot; &quot;);
					var count:int = 0;
					for each( var slide:String in slides )
					{
						switch( slide )
						{
							case &quot;MESSAGES&quot;:
								_totalMessages = slides[count + 1];
								break;
							case &quot;UNSEEN&quot;:
								_newMessages = slides[count + 1];
								break;
						}
						count++;
					}
					result_txt.text = _newMessages + &quot; mensajes nuevos, de &quot; + _totalMessages + &quot; en total&quot;;
					out_txt.text += _totalMessages;
					out_txt.text += _newMessages;
					_action = null;
					_server.close();
				}
			}

			private function start():void
			{
				out_txt.text = &quot;iniciando Conexion\n&quot;;
				if( _server != null &amp;&amp; _server.connected )
				{
					_server.close();
				}
				if( _username.length &amp;&amp; _password.length )
				{
					_action = CONNECT;
					_server.connect(INCOMING_SERVER, PORT);
					cursorManager.setBusyCursor();
				}else
				{
					Alert.show(&quot;Escribe tus credenciales..&quot;, &quot;Error&quot;);
				}
			}

		]]&gt;
	&lt;/fx:Script&gt;
	&lt;s:Label x=&quot;10&quot; y=&quot;17&quot; text=&quot;Gmail username:&quot;/&gt;
	&lt;s:Label x=&quot;10&quot; y=&quot;45&quot; text=&quot;Gmail password:&quot;/&gt;
	&lt;s:TextInput y=&quot;10&quot; id=&quot;username_txt&quot; change=&quot;_username = username_txt.text&quot; right=&quot;10&quot; left=&quot;120&quot;/&gt;
	&lt;s:TextInput y=&quot;40&quot; id=&quot;password_txt&quot; change=&quot;_password = password_txt.text&quot; displayAsPassword=&quot;true&quot; right=&quot;10&quot; left=&quot;120&quot;/&gt;
	&lt;s:Button y=&quot;70&quot; label=&quot;Tell me!!&quot; click=&quot;start()&quot; right=&quot;10&quot;/&gt;
	&lt;s:Label x=&quot;10&quot; y=&quot;100&quot; width=&quot;280&quot; id=&quot;result_txt&quot;/&gt;
	&lt;s:TextArea id=&quot;out_txt&quot; editable=&quot;false&quot; right=&quot;10&quot; bottom=&quot;10&quot; top=&quot;130&quot; left=&quot;10&quot;/&gt;
&lt;/s:WindowedApplication&gt;
</pre>
<h1>Descarga</h1>
<div style="width: 200px; margin: 10px; text-align: center">
	<p><a rel="nofollow" title="Download version 0.1 of Gmail-Imap.air" href="http://klr20mg.com/downloads/Gmail-Imap.air"><img src="http://klr20mg.com/wp-content/plugins/drain-hole/images/download.png" alt="download" width="128" height="128"/></a></p>

	<table class="download">
		<tr>
			<th>Download:</th>
			<td><a rel="nofollow" title="Download version 0.1 of Gmail-Imap.air" href="http://klr20mg.com/downloads/Gmail-Imap.air">Gmail-Imap.air</a></td>
		</tr>
		<tr>
			<th>Version:</th>
			<td>0.1</td>
		</tr>
		<tr>
			<th>Updated:</th>
			<td>February 26, 2010</td>
		</tr>
		<tr>
			<th>Size:</th>
			<td>870.16 KB</td>
		</tr>
	</table>
</div>

<p>Espero les sea de ayuda y nos estamos leyendo.</p>
]]></content:encoded>
			<wfw:commentRss>http://klr20mg.com/2010/02/26/air-2-0-conexin-imap-mediante-securesocket/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Obtener tweets usando PHP &amp; Flex 4 (Gumbo)</title>
		<link>http://klr20mg.com/2009/12/09/obtener-tweets-usando-php-flex-4-gumbo/</link>
		<comments>http://klr20mg.com/2009/12/09/obtener-tweets-usando-php-flex-4-gumbo/#comments</comments>
		<pubDate>Wed, 09 Dec 2009 23:17:49 +0000</pubDate>
		<dc:creator>Tmeister</dc:creator>
				<category><![CDATA[Flex 4]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[twitter]]></category>
		<category><![CDATA[api ejemplo]]></category>

		<guid isPermaLink="false">http://klr20mg.com/?p=512</guid>
		<description><![CDATA[En este ejemplo, ya no muy básico, les mostrare como obtener los últimos tweets de un usuario y mostrarlos en Flex 4 (Gumbo) para ello haremos uso de PHP como gateway, con PHP obtendremos los tweets por medio del API de Twitter y los desplegaremos en forma de XML para poder leerlos en Flex. Este ejemplo esta hecho [...]]]></description>
			<content:encoded><![CDATA[<p>En este <a href="http://klr20mg.com/category/flex-4/">ejemplo</a>, ya no muy básico, les mostrare como obtener los últimos tweets de un usuario y mostrarlos en <a href="http://klr20mg.com/category/flex-4/">Flex 4 (Gumbo)</a> para ello haremos uso de PHP como gateway, con PHP obtendremos los tweets por medio del <a href="http://apiwiki.twitter.com/">API de Twitter</a> y los desplegaremos en forma de XML para poder leerlos en Flex.</p>
<div class="info">Este ejemplo esta hecho con <a href="http://labs.adobe.com/technologies/flashbuilder4/" target="_blank">Flash Builder 4 Beta 2</a> y necesita el <a href="https://www.adobe.com/go/getflashplayer">FlashPlayer 10</a> para poder visualizarlo correctamente</div>
<h1>Ejemplo</h1>
<div>
<object width="600" height="350">
<param name="movie" value="http://klr20mg.com/flex/gumbo/last-tweet/tweets.swf"></param>
<param name="quality" value="high"></param>
<param name="wmode" value="window"></param>
<param name="menu" value="false"></param>
<param name="bgcolor" value="#2a2a2a"></param>
<param name="allowFullScreen" value="true"></param>
<embed type="application/x-shockwave-flash" width="600" height="350" src="http://klr20mg.com/flex/gumbo/last-tweet/tweets.swf" quality="high" bgcolor="#2a2a2a" wmode="window" menu="false" allowFullScreen="true" ></embed>
</object>
</div>
<p>Lo primero que necesitamos es crear el script en PHP para poder conectarnos al <a href="http://apiwiki.twitter.com/">API de Twitter</a>, obtener los tweets y desplegarlos en XML.</p>
<h1>PHP</h1>
<pre class="brush: php;">
&lt;?php
/**
 * get_user_tweets()
 *
 * @param mixed $username
 * @param integer $count
 * @return array $out
 */
function get_user_tweets($username, $count = 10)
{
	/**
	 * URL para obtener los tweets en formato JSON
	 * Utilizaremos curl para hacer la conexion al API de Twitter
	 * */
	$url = 'http://twitter.com/statuses/user_timeline/'.$username.'.json?count='.$count;
	$curl = curl_init();

	/**
	 * Iniciamos CURL pasando que URL vamos a cargar
	 * */
	curl_setopt($curl, CURLOPT_URL, $url);
	/**
	 * Indicamos que querremos el output de regreso
	 * */
	curl_setopt ($curl, CURLOPT_RETURNTRANSFER, 1);
	/**
	 * Ponemos un TimeOut al script
	 */
	curl_setopt ($curl, CURLOPT_CONNECTTIMEOUT, 10);

	/**
	 * Ejecutamos CURL
	 */
	$json = curl_exec($curl);

	/**
	 * Cerramos la conexion
	 */
	curl_close($curl);

	/**
	 * Tomanos el resultado (JSON) y lo parseamos en PHP
	 */
	$tweets = json_decode($json);
	$out;

	/**
	 * Por ultimo por cada tweet tomanos el contenido y lo metemos en un Array
	 */
	foreach($tweets as $tweet)
	{
		$out[] = $tweet-&gt;text;
	}

	return $out;
}

/**
 * Con la informacion obtenida del API construimos un XML y lo mostramos
 */
$out = '&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf8&quot;?&gt;';
$out .= &quot;&lt;tweets&gt;&quot;;
$tweets = get_user_tweets('tmeister', 10);
foreach($tweets as $tweet)
{
	$out .= &quot;&lt;tweet&gt;$tweet&lt;/tweet&gt;&quot;;
}
$out .= &quot;&lt;/tweets&gt;&quot;;
header (&quot;content-type: text/xml&quot;);
echo $out;
?&gt;
</pre>
<p>El resultado del script lo puedes ver en <a href="http://klr20mg.com/flex/gumbo/last-tweet/last.php">http://klr20mg.com/flex/gumbo/last-tweet/last.php</a></p>
<h1>MXML</h1>
<p>Una vez que tenemos el XML solo falta mostrar su contenido en Flex.</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;s:Application
    xmlns:fx=&quot;http://ns.adobe.com/mxml/2009&quot;
    xmlns:s=&quot;library://ns.adobe.com/flex/spark&quot;
    xmlns:mx=&quot;library://ns.adobe.com/flex/halo&quot;
    width=&quot;100%&quot;
    height=&quot;100%&quot;
    creationComplete=&quot;{service.send()}&quot;
    viewSourceURL=&quot;http://klr20mg.com/flex/gumbo/last-tweet/srcview/index.html&quot;
    &gt;

    &lt;fx:Script&gt;
        &lt;![CDATA[
            import mx.collections.ArrayCollection;
            import mx.controls.Alert;
            import mx.rpc.events.FaultEvent;
            import mx.rpc.events.ResultEvent;

            [Bindable]
            private var _tweets:ArrayCollection;

            protected function service_resultHandler(event:ResultEvent):void
            {

                _tweets = new ArrayCollection();

                for each( var tweet:String in event.result.tweet  )
                {
                    _tweets.addItem(tweet);
                }
            }

            protected function service_faultHandler(event:FaultEvent):void
            {
                Alert.show(event.fault.faultString, &quot;Error&quot;);
            }

        ]]&gt;
    &lt;/fx:Script&gt;

    &lt;fx:Declarations&gt;
        &lt;s:HTTPService
            id=&quot;service&quot;
            result=&quot;service_resultHandler(event)&quot;
            fault=&quot;service_faultHandler(event)&quot;
            url=&quot;http://klr20mg.com/flex/gumbo/last-tweet/last.php&quot;
            showBusyCursor=&quot;true&quot;
            resultFormat=&quot;e4x&quot;
            &gt;
        &lt;/s:HTTPService&gt;
    &lt;/fx:Declarations&gt;

    &lt;mx:VBox verticalCenter=&quot;0&quot; horizontalCenter=&quot;0&quot;&gt;
        &lt;mx:Repeater id=&quot;rep&quot; dataProvider=&quot;{_tweets}&quot;&gt;
            &lt;s:Label text=&quot;{rep.currentItem}&quot; /&gt;
            &lt;mx:HRule width=&quot;100%&quot; /&gt;
        &lt;/mx:Repeater&gt;
    &lt;/mx:VBox&gt;

&lt;/s:Application&gt;
</pre>
<p>Con esto ya podemos mostrar los últimos tweets de un timeline sin necesidad de usar librerias ni de PHP o de ActionScript.</p>
]]></content:encoded>
			<wfw:commentRss>http://klr20mg.com/2009/12/09/obtener-tweets-usando-php-flex-4-gumbo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cambiando el symbolColor en el &#8220;Spark CheckBox&#8221;</title>
		<link>http://klr20mg.com/2009/12/08/cambiando-el-symbolcolor-en-el-spark-checkbox/</link>
		<comments>http://klr20mg.com/2009/12/08/cambiando-el-symbolcolor-en-el-spark-checkbox/#comments</comments>
		<pubDate>Tue, 08 Dec 2009 14:00:20 +0000</pubDate>
		<dc:creator>Tmeister</dc:creator>
				<category><![CDATA[Ejemplos]]></category>
		<category><![CDATA[Flex 4]]></category>
		<category><![CDATA[checkbox]]></category>
		<category><![CDATA[Gumbo]]></category>
		<category><![CDATA[spark]]></category>
		<category><![CDATA[symbolColor]]></category>

		<guid isPermaLink="false">http://klr20mg.com/?p=492</guid>
		<description><![CDATA[Este es una entrada de la serie de ejemplos basicos de Flex 4 (Gumbo) En el siguiente ejemplo les mostrare como pueden cambiar el color de la marca de seleccion de un Spark Checkbox en Flex 4, asi como el basecolor de fondo y el texto del label. Este ejemplo esta hecho con Flash Builder [...]]]></description>
			<content:encoded><![CDATA[<p>Este es una entrada de la <a href="http://klr20mg.com/category/flex-4/">serie de ejemplos basicos de Flex 4</a> (Gumbo)</p>
<p>En el siguiente ejemplo les mostrare como pueden cambiar el color de la marca de seleccion de un Spark Checkbox en Flex 4, asi como el <a href="http://klr20mg.com/2009/12/07/cambiando-el-color-de-fondo-del-spark-button" target="_blank">basecolor de fondo</a> y el texto del label.</p>
<div class="info">Este ejemplo esta hecho con <a href="http://labs.adobe.com/technologies/flashbuilder4/" target="_blank">Flash Builder 4 Beta 2</a> y necesita el <a href="https://www.adobe.com/go/getflashplayer">FlashPlayer 10</a> para poder visualizarlo correctamente</div>
<h1>Ejemplo</h1>
<div>
<object width="600" height="200">
<param name="movie" value="http://klr20mg.com/flex/gumbo/checkbox/checkBox.swf"></param>
<param name="quality" value="high"></param>
<param name="wmode" value="window"></param>
<param name="menu" value="false"></param>
<param name="bgcolor" value="#2a2a2a"></param>
<param name="allowFullScreen" value="true"></param>
<embed type="application/x-shockwave-flash" width="600" height="200" src="http://klr20mg.com/flex/gumbo/checkbox/checkBox.swf" quality="high" bgcolor="#2a2a2a" wmode="window" menu="false" allowFullScreen="true" ></embed>
</object>
</div>
<p>Para ello usaremos las propiedades</p>
<ul>
<li>symbolColor</li>
<li><a href="http://klr20mg.com/2009/12/07/cambiando-el-color-de-fondo-del-spark-button">baseColor</a></li>
<li>color</li>
</ul>
<h1>MXML</h1>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;s:Application
    xmlns:fx=&quot;http://ns.adobe.com/mxml/2009&quot;
    xmlns:s=&quot;library://ns.adobe.com/flex/spark&quot;
    xmlns:mx=&quot;library://ns.adobe.com/flex/halo&quot;
    width=&quot;100%&quot; height=&quot;100%&quot;
 &gt;
   &lt;mx:ApplicationControlBar width=&quot;100%&quot; cornerRadius=&quot;0&quot;&gt;
        &lt;s:Label text=&quot;baseColor:&quot; /&gt;
        &lt;mx:ColorPicker id=&quot;colorPickerBase&quot; selectedColor=&quot;#cccccc&quot; /&gt;
        &lt;s:Label text=&quot;symbolColor:&quot; /&gt;
        &lt;mx:ColorPicker id=&quot;colorPickerSymbol&quot; selectedColor=&quot;#000000&quot; /&gt;
        &lt;s:Label text=&quot;textColor:&quot; /&gt;
        &lt;mx:ColorPicker id=&quot;colorPickerText&quot; selectedColor=&quot;#000000&quot; /&gt;
    &lt;/mx:ApplicationControlBar&gt;

    &lt;s:CheckBox
        label=&quot;Spark CheckBox&quot;
        selected=&quot;true&quot;
        baseColor=&quot;{colorPickerBase.selectedColor}&quot;
        symbolColor=&quot;{colorPickerSymbol.selectedColor}&quot;
        color=&quot;{colorPickerText.selectedColor}&quot;
        horizontalCenter=&quot;0&quot; verticalCenter=&quot;0&quot;
    /&gt;

&lt;/s:Application&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://klr20mg.com/2009/12/08/cambiando-el-symbolcolor-en-el-spark-checkbox/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cambiando el color de fondo del &#8220;Spark Button&#8221;</title>
		<link>http://klr20mg.com/2009/12/07/cambiando-el-color-de-fondo-del-spark-button/</link>
		<comments>http://klr20mg.com/2009/12/07/cambiando-el-color-de-fondo-del-spark-button/#comments</comments>
		<pubDate>Mon, 07 Dec 2009 21:05:43 +0000</pubDate>
		<dc:creator>Tmeister</dc:creator>
				<category><![CDATA[Flex 4]]></category>
		<category><![CDATA[BaseColor]]></category>
		<category><![CDATA[Button]]></category>
		<category><![CDATA[Ejemplos]]></category>
		<category><![CDATA[Gumbo]]></category>

		<guid isPermaLink="false">http://klr20mg.com/?p=475</guid>
		<description><![CDATA[Con este post comenzare una serie de ejemplos básicos para irnos metiendo a lo nuevo de Flex 4 (aka Gumbo), su nuevo modelo de componentes y nuevas características. En este primer ejemplo mostrare como se puede cambiar el &#8220;baseColor&#8221; o background del componente Spark Button. Antes de continuar cabe resaltar que estos ejemplo estan hechos [...]]]></description>
			<content:encoded><![CDATA[<p>Con este post comenzare una serie de <strong>ejemplos básicos</strong> para irnos metiendo a lo nuevo de Flex 4 (aka Gumbo), su nuevo modelo de componentes y nuevas características.</p>
<p>En este primer ejemplo mostrare como se puede cambiar el &#8220;baseColor&#8221; o background del componente Spark Button.</p>
<div class="info">Antes de continuar cabe resaltar que estos ejemplo estan hechos con <a href="http://labs.adobe.com/technologies/flashbuilder4/" target="_blank">Flash Builder 4 Beta 2</a> y se necesita el <a href="https://www.adobe.com/go/getflashplayer">FlashPlayer 10</a> para poder visualizarlos correctamente</div>
<h1>Ejemplo</h1>
<div>
<object width="600" height="200">
<param name="movie" value="http://klr20mg.com/flex/gumbo/basecolor/baseColor.swf"></param>
<param name="quality" value="high"></param>
<param name="wmode" value="window"></param>
<param name="menu" value="false"></param>
<param name="bgcolor" value="#2a2a2a"></param>
<param name="allowFullScreen" value="true"></param>
<embed type="application/x-shockwave-flash" width="600" height="200" src="http://klr20mg.com/flex/gumbo/basecolor/baseColor.swf" quality="high" bgcolor="#2a2a2a" wmode="window" menu="false" allowFullScreen="true" ></embed>
</object>
</div>
<p>Hay 3 maneras como podemos cambiar el baseColor, usando MXML, Actionscript o CSS.</p>
<h1>MXML</h1>
<p>Este es el source del ejemplo anterior.</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;

&lt;s:Application
    xmlns:fx=&quot;http://ns.adobe.com/mxml/2009&quot;
    xmlns:s=&quot;library://ns.adobe.com/flex/spark&quot;
    xmlns:mx=&quot;library://ns.adobe.com/flex/halo&quot;
    width=&quot;100%&quot; height=&quot;100%&quot;
&gt;
    &lt;mx:ApplicationControlBar width=&quot;100%&quot;&gt;
        &lt;s:Label text=&quot;baseColor: &quot; /&gt;
        &lt;mx:ColorPicker id=&quot;colorSelector&quot; selectedColor=&quot;#cccccc&quot; /&gt;
    &lt;/mx:ApplicationControlBar&gt;

    &lt;s:Button
        id=&quot;button&quot;
        baseColor=&quot;{colorSelector.selectedColor}&quot;
        horizontalCenter=&quot;0&quot;
        verticalCenter=&quot;0&quot;
        label=&quot;baseColor&quot;
    /&gt;

&lt;/s:Application&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://klr20mg.com/2009/12/07/cambiando-el-color-de-fondo-del-spark-button/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
