domingo, 17 de mayo de 2009

Acceder Gdata desde Flex

Dada la dificultad de acceder a Gdata desde flex, accederemos desde Javascript .

Nuestro primer acercamiento sera el uso del api de Blogger y de Feeds .
Son parecidos aunque diferentes. Los dos Apis trabajan con formatos Atom , que es una especificación normalizada de intercambio de datos basados en Noticias, o Post's de blog.
La idea es llamar desde Flex a una función JavaScript que hace la recepción de la información, usando las funciones proporcionadas por el Api JavaScript de google.


La consulta a GData es asincrona, eso significa que se lanza la consulta, y se sigue ejecutando el código JavaScript. Cuando se obtiene la respuesta es cuando se procesa por la función que lo maneja.



Veremos varias cosas.
Llamar a JavaScript desde Flex.
Llamar a Flex desde JavaScript. Pasar datos HTML en cadenas XML.


a) Llamar a JavaScript desde Flex.


Veamos la función en Flex (ActionScript) que hace una llamada "genérica " a una función JavaScript.

public static function Call2J(fun:String, o:Object=null):Object {
try
{
if (ExternalInterface.available) {
if (o==null){
o = {};
}
return ExternalInterface.call(fun, o);
}

}
catch (e:Error) {
Alert.show("No se pudo procesar la peticion JavaScript " + e.message);
}
return "";

}

Esta función realzaría una llamada a la función con en nombre pasado en la cadena fun pasándole como parámetro el objeto o. Devuelve el resultado de la función JavaScript.


A continuación, estos serian ejemplo que llaman a nuestra función genérica

public function GetFeed():void
{

var o:Object={}
o.URL='http://www.google.com/reader/public/atom/user%2F05929107252017748980%2Flabel%2FAjox';
Call2J('GetFlexFeed',o);

}



public function GetBlog():void
{

var o:Object={}
o.url='';
Call2J('GetFlexBlog',o);


}

b) Llamar a Flex desde JavaScript.

Publicar Función

Para llamar a una función ActionScript desde JavaScript, primero esta debe ser una función "publicada" explícitamente por nuestro programa Flex. Para Publicar una función usaremos lo siguiente:

import flash.external.*; //tenemos que importar el interface flash.external


private function onCreationComplete():void // este seria un ejemplo de método creationComplete del programa.
{
ExternalInterface.addCallback('resultado', resultaBlog); // esta es la forma de publicar una función.
// * La publicamos con nombre resultado, y lo asociamos a la función resultaBlog.
GetFeed(); // o GetBlog();

}

Ejemplo de Función

Esto es una forma de montarse el manejo de la respuesta obtenida .

public function resultaBlog(e:Object):void // esta es la función Flex que llamaremos desde Javascript con el resultado.
{
// este código puede ser optimizado pero esta paso por paso para mejor comprensión.
// la función debe recibir un objeto "e" que lleva el campo "a" con la información en Texto.
var ss:String=e.a;
var s:String=ss.toUpperCase() // esto pudiera ser no necesario, pero queremos trabajar con texto en mayúsculas, y lo cambiamos desde aquí.
var x:XML=XML(s);
datos=XMLList(x.ITEM);
fillrss(datos) // Una vez convertido en XMLList los datos, lo pasamos a la función que los va a manejar finalmente.

}



// funcion que maneja finalmente los datos. Convierte de XML a un ArrayCollection, que sera el DataProvider de la tabla que muestra los resultados.
public function fillrss (e:Object):void {


datas.removeAll();
var num:int=0;
var temp:Object = {};
for each(var row:XML in e)
{
var xxx:XMLList=row.elements("*");
var nunu:int=xxx.length();
  temp = {};
for (var k=0;k<nunu;k++) {
var na:String= xxx[k].name();
var da:String= xxx[k]
temp[na]=da;
}
datas.addItem(temp);
num++
}

}


Veamos la parte puesta en el JavaScript

// Esta es la funcion que llamamos directamente desde flex. El objeto ob, lleva el campo URL que es la direccion del Feed a leer.

function GetFlexFeed(ob) {

var feed = new google.feeds.Feed (ob.URL);

feed.includeHistoricalEntries(); // Decimos que queremos entradas antiguas también
feed.setNumEntries(250); // ponemos el tamaño máximo de número de entradas.

// Llama a la funcion que carga el feed, pasándole como parámetro la función que menejara la respuesta.
feed.load(feedLoaded);
}


Esta es la función que maneja la respuesta del Feed.
Aunque puede hacerse de muchas formas, esta vez lo que haremos es una cadena XML con el resultado completo de la consulta. Y luego invocaremos a la función en Flex.
Solo puntalizar que el contenido del campo feed.content, es un contenido que puede tener código HTML,
El código HTML lleva marcas de tipo <b> o <header>, en algunos casos no estan bien "Terminadas" y esto puede romper la lectura correcta como cadena XML.
Con lo que ese dato lo pasaremos entre cadenas '<![CDATA[' y ']]>' que permite tener cualquier contenido sin cortar la comunicación XML.

function feedLoaded(result) {

if (!result.error) {

var html = '<items>';

for (var i = 0; i < result.feed.entries.length; i++) {
var en = result.feed.entries[i];
)
var postTitle = en.title;
var postURL = en.link;
var con= en.content;

var pubDate = en.publishedDate;
html += '<item><url>' + postURL + '</url><title>'
+ postTitle + '</title><content>'+
'<![CDATA['+con+']]>'+
'</content>'+
'<fecha>'+pubDate+'</fecha>'+
'</item>';
}
html += '</items>';
var o={}
o.a=html;
var flashObject = thisApp ();
flashObject.resultado (o)
}
}


Resumen.

Este es el mapa general de las funciones :







Conclusiones.

No es tan dificil plantearse acceso a otro tipo de datos del API de Google usando este "metodo" sin tener que hacer uso de librerias especificas en ActionScript.

No hay comentarios: