En este artículo cuento mi experiencia de creación de la aplicación de iOs TimeBox ,desde el estudio de mercado, diseño, y elaboración de la interfaz gráfica hasta la programación, creación de la base de datos y la aplicación web para redes sociales.
Lo primero que debemos hacer es tener claro qué tipo de aplicación queremos crear, para eso hay que tener una buena idea, y si la tenéis pero la aplicación ya está hecha, entonces comprar/bajaros todas las aplicaciones que han implementado vuestra idea y estudiarlas para encontrar en qué fallan, cómo las podéis mejorar y combinar, es decir, encontrad una motivación para programar, porque esto es duro amigos jeje (más…)

Guía de uso del Modelo de Datos de iOS:
Podéis ver que el editor trae un soporte para la vista de un bonito Diagrama de Entidad/Relación de nuestra BD.//Crear y configurar una instancia de una entidad Event - (void) createEvent { Event *event = (Event *) [NSEntityDescription insertNewObjectForEntityForName:@"Event" inManagedObjectContext: managedObjectContext]; //Crear un tipo de dato coordenada para mapas de google, así nos acostumbramos a usarlos: CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(37.123123, -3.321321); //Ahora lo tenemos muy fácil ,sólo tenemos que usar los setters & getters generados por XCode: [event setLatitude:[NSNumberWithFloat:coordinate.latitude]]; [event setLongitude:[NSNumberWithFloat:coordinate.longitude]]; [event setCreationDate:[NSDate date]]; //"date" es la fecha de hoy [event setTitle:@"Mi primer evento"]; }
y eso sería todo el código, ahora pasamos a grabar los datos para hacerlos persistentes
NSError *error; if ([managedObjectContext save:&error]){ //prestar especial atención al ampersand...referencia de memoria! //Gestión del error aquí }
Podemos intentar capturar errores con una captura de excepciones (@try { } @catch (NSException *exception) { } @finally { } ) pero esto no es recomendable, además de que debemos recordar la cadena de respondedores, aquí se aplica el mismo cuento y tendríamos que ir hacia arriba en la lógica de la programación para capturar la verdadera excepción de la pila de llamadas…cosa que es bastante tediosa, por eso es mejor pensar las cosas bien y hacerlas mejor jeje, con la práctica todo se consigue ;)
Fetch Request -> execute!

Si queremos recuperar el objeto no tenemos más que usar, como se hace en php y mysql una petición tipo “fetch”, es decir, con NSFetchRequest especificamos la entidad, aquí tenéis un ejemplo completo.
En resumidas cuentas, hay que crear un objeto NSFetchRequest, reutilizamos el objeto de la descripción de una entidad y asociamos esta al primero con setEntity:
NSFetchRequest *request = [[NSFetchRequest alloc] init]; //cuidado que esto no se libera. lo hace sólo...:O NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext: managedObjectContext]; [request setEntity:entity]; //Para realizar un ORDER BY fecha típico usamos un descriptor de ordenación: NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"creationDate" ascending:NO]; NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil]; [request setSortDescriptors:sortDescriptors]; //ahora sí, liberamos los descriptores [sortDescriptor release]; [sortDescriptors release]; //Con todo configurado, vamos a ejecutar la consulta y guardar el resultado en una matriz modificable: NSError *error1; //Atención al parámetro "mutableCopy"!! NSMutableArray *results = [[managedObjectContext executeFetchRequest:request &error1] mutableCopy]; if ( results == nil ){ //Manejar el error! } //Para borrar necesitamos un NSError igual que cuando guardamos con save NSError *error2; [managedObjectContext deleteObject:objetoEventoParaBorrar]; if (
Recordamos del curso de servicios web que escribir XML y código de un servicio web no es tarea de humanos, para eso existen frameworks que harán el trabajo duro por nosostros, Fremont es la parte cliente, en Objective C, para la parte del servidor tenemos los transformadores que ya vimos, BPEL, etc.
Gracias al uso de un servidor asociado a Google App Engine, crearemos un conjunto de servicios usando Google Web Toolkit 2.3.0 , que una vez probados en red local podremos desplegar en el servidor Java de GAE asociado a nuestra cuenta de usuario.
Pasos para la creación de un servidor de datos por medio de servicios web con Eclipse:

Una vez que hayamos creado nuestras inicializaciones de datos de nuestro modelo (instanciado las clases oportunas), debemos guardarlos usando un gestor de Persistencia, lo que viene a ser una clase de JDOHelper.getPersistenceManagerFactory("transactions-optional"); que por medio de la función makePersistent(clase_instanciada) se almacenará (después debemos hacer un close(), claro jeje)
Como ya hemos visto antes el funcionamiento de la persistencia de datos en iOS con un Modelo de Datos, pasaré directamente al análisis de un XML, aunque esto debería hacerse automáticamente con un framework como Fremont, lo importante es que os quedéis con que las clases que permiten estas tareas son NSURL, NS/Mutable\URLRequest,y NSURLConnection. Estas descargan los datos y podemos realizar el análisis sintáctico con varios tipos de "parser", SAX: envío de notificaciones a medida que el analizador sintáctico va leyendo la cadena XML recibida por NSURL, o bien DOM: es un analizador que lee toda la cadena XML y construye su representación completa. Para utilizar estos analizadores debemos incluir al proyecto el fichero libxml2 de las librerías del SDK (tanto SAX como DOM), o bien NSXMLParser (sólo SAX). Aunque existen alternativas como TBXML, TouchXML, KissXML, TinyXML, GDataXML, etc. --> ver comparativa >>
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:xmlData]; //recibidos por NSURL
[parser setDelegate:self];
A partir de aquí, se trata de usar los eventos del delegado (eventos de NSXMLParserDelegate) que son: didStartElement -> empieza un elemento, didEndelement, didStartDocument, etc. de forma que al principio del documento inicializamos los datos (un array modificable, por ejemplo), y cada vez que encuentra un elemento de tipo titulo pues añade un elemento al array y luego al terminar un elemento de tipo evento, pues añade el array de propiedades de un evento al array de eventos...fácil...Importante implementar también la función:
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError;

La utilización de caché tanto para datos persistentes como para datos dinámicos es importante a la hora de realizar aplicaciones para móviles ya que está muy penalizado el uso de conexiones a Internet, es más rentable llegar a un equilibrio de carga de datos entre el servicio web y los usuarios de los dispositivos, por eso os presento las dos tareas a realizar en un proyecto serio...
En esta dirección encontraréis un framework sorprendente para realizar tareas con análisis sintácticos de XML, descarga de datos a través de urls, caché, etc.
Es una maravilla ver como funcionan los ejemplos, hay uno,especial de caché en el que se dispone una serie de descargas de imágenes y a cada una de ellas se le asocia un puesto en una clase cola-de-espera que tiene asociada una barra de progreso por lo que va actualizando el estado conforme se van descargando los datos...impresionante :)
Lo que podéis hacer es utilizar una caché para guardar la información en un modelo de datos, durante unos días en el iDevice, pasados esos días, vuelve a sincronizarse con el servicio de Google App Engine y reescribimos toda la estructura de datos del programa con nueva información, así nos ahorramos realizar peticiones al servidor continuamente, lo que ralentizaría mucho la carga y si la aplicación es muy usada puede generar un cuello de botella que ha de evitarse.
Para hacer esto nos viene bien los datos de configuración de un usuario, lo veremos en la próxima entrega del curso de aplicaciones para iOS, aquí mismo.
Recordar que podéis utilizar recursos como http://wiki.gnustep.org y http://stackoverflow.com/ para solucionar vuestras dudas tanto con Objective C como con Java Google App Engine y GWT.
En cualquier caso, los ejercicios de esta entrega están claros cuáles son: desplegar una aplicación en GAE con GWT y pasar los datos a un modelo de datos de XCode (SQlite)...hay cientos de tutoriales en internet sin embargo si tenéis cualquier duda, mandadme el fichero y lo intentaré corregir.
<< Volver al curso de programación de aplicaciones de iOS | Siguiente lección: Configuración y traducción de una aplicación de iOS >>
Desde que Facebook empezó a tener éxito, los clones de redes sociales no pararon de aparecer, sobre todo webs de contactos como zoosk, badoo, linked in, …o las miles de redes más, cada una con su propósito, sin embargo las necesidades del público son tan dispares que empezaron a salir generadores online de redes sociales, no contentos con esto, ya que a nadie le interesa tener alojada una red social en las máquinas de alguien que no conoce, aparecieron generadores de redes sociales pero esta vez ,instalables en un servidor propio…una de esas opciones, de la más extendida ,es elgg…
Con elgg podemos simular un facebook, y digo simular porque no trae soporte para clústers, ni gestor de aplicaciones con APi externa, ni chat integrado, pero sí trae las herramientas para programar todas estas cosas, empezando por el muro, existe un componente llamado riverdash que lo implementa, en mi caso he estado extendiendo la funcionalidad de este plugin para un cliente y tengo que decir que el código de elgg aún tiene que madurar ,sin embargo entraña un potencial muy grande que puede aprovecharse tanto para construir una buena red social como para una aplicación de un grupo más reducido de personas que necesiten compartir información.
Podemos consultar la Wiki de Elgg aquí y descargarnos la última versión aquí.
Para añadir funcionalidades a esta red social personal se utiliza el directorio “mod” donde creamos un nuevo subdirectorio con el nombre de nuestro módulo, llamémoslo “saludo”, dentro, si creamos un fichero llamado “start.php” elgg cargará nuestro módulo, en dicho fichero se especifican las inicializaciones a realizar; lo primero después de esto es crear un subdirectorio dentro de “saludo” para las vistas, llamado “views”…aquí empieza a complicarse, tenemos varios tipos de vistas, lo normal es xhtml así que por defecto se llama al subdirectorio dentro de views , “default”, ahora, si es un widget (zona flotante que se puede colocar en cualquier lugar de las plantillas de la web) pues irá dentro del subdirectorio de default, “widgets”, y vamos a llamar al nuevo fichero “vista.php”, luego la ruta completa es
/mod/saludo/views/default/widgets/vista.php , y el código para esta vista es:
[source language="php"]
[/source]
para que podamos gestionar el widget desde la administración iremos a /mod/saludo/start.php y lo dejaremos así:
[source language="php"]
function iniciar_saludo() {
add_widget_type(‘saludo’, ‘Mod de Saludo’, ‘Simplemente saluda’);
}
register_elgg_event_handler(‘init’,'system’,'iniciar_saludo’);
[/source]
De forma que elgg ya sabe qué es lo que tiene que hacer con nuestro nuevo módulo…
Para complicarlo un poco más y pasarle datos a nuestro módulo usaremos una vista de elgg, creando un fichero llamado hola.php donde estaba vista.php, con el siguiente contenido:
[source language="php"]
Tu saludo:
echo elgg_view('input/text', array( 'internalname' => ‘params[mensaje]‘,
‘value’ => $vars['entity']->mensaje,
‘class’ => ‘hola-input-text’ ) );
?>
[/source]
así, especificamos a elgg que queremos mostrar un tipo de vista basada en un input text con el nombre “mensaje” y el valor es el que tenga la propia entidad (al principio ninguno) en su atributo mensaje, la class es CSS…
Ahora, para que la vista.php muestre el saludo enviado, necesitamos cambiarla para que quede así:
[source language="php"]
[/source]
Para más información acerca de las vistas pinchar aquí.
La gestión de idiomas se lleva por medio de un array de valores en /mod/saludo/languages/es.php, el índice o clave de una palabra o frase a almacenar contiene el prefijo del módulo, en nuestro caso “saludo:____” , donde ___ es el resto de la llave, por ejemplo, para inicio ->
[source language="php"]
$espanol = array ( “saludo:inicio” => “Inicio”);
$english = array(“saludo:inicio” => “Home”);
add_traslation(“es”, $espanol);
add_traslation(“en”, $english);
//Para utilizar las claves:
echo elgg_echo(“saludo:inicio”);
[/source]
En este vídeo se puede comprobar como se ha modificado elgg para añadir un motor tipo “muro” de facebook, se ha añadido la funcionalidad de mostrar comentarios, eventos, “me gusta” y “no me gusta”, enviar a redes sociales, etc.
Los encargos que he realizado están asociados a la creación de herramientas (plugins) y modificaciones del núcleo para importar y exportar contenido entre redes sociales y elgg. Desde Blogger hasta Facebook pasando por WordPress, las “tools” que he diseñado específicamente importan y exportan entradas del river-dashboard, también conocido como el famoso muro en facebook, pero adaptado para elgg.
Crear un plugin como extensión de otro para elgg:
1.- crear directorio en /mod/nombre_plugin
2.- crear /mod/nombre_plugin/manifest.xml
[sourcecode language="xml"]
3.- crear /mod/nombre_plugin/start.php
donde al menos registraremos una función para la carga del plugin y otra función para manejar los eventos, opcionalmente añadiremos acciones también (funciones,claro).
register_elgg_event_handler('init','system','nombre_plugin_init'); register_elgg_event_handler('pagesetup','system','nombre_plugin_pagesetup');
En el caso en que queramos permitir el uso de preferencias por usuario del plugin, usaremos en start.php -función nombre_plugin_init()-, el siguiente código:
register_plugin_hook('usersettings:save','user','nombre_plugin_user_settings_save');
La función para guardar estas preferencias debe ser algo como:
function nombre_plugin_user_settings_save(){ //sólo usuario registrado y propietario de la cuenta a editar opciones gatekeeper(); $user = page_owner_entity(); if (!$user) { $user = $_SESSION['user']; } $user->nombre_input = get_input('nombre_input','valor_por_defecto'); }
Evidentemente tenemos que añadir las vistas como página
en la función nombre_plugin_pagesetup:
//Añadir los campos de configuración de usuario extend_elgg_settings_page( 'nombre_plugin/settings/usersettings', 'usersettings/user' );
y claro, necesitamos crear el fichero que referenciamos, en
/mod/nombre_plugin/views/default/settings/usersettings.php
donde colocaremos los (html) que necesitemos. Para obtener los valores en dicha vista de los propios inputs, usaremos
$user = page_owner_entity();
y los valores están dentro de esta clase: $user->nombre_input...
Como truquito que me gusta utilizar, para crear una lista de valores con un select, usar las funciones implode para guardar el dato y split para el dato leído e interpretarlo.
Si queremos que el plugin tenga opciones para el administrador creamos el directorio
/mod/nombre_plugin/views/settings/nombre_plugin/
y dentro colocamos el fichero edit.php. Aquí lo único que tenemos que hacer es escribir por pantalla los campos input que queramos como opciones de administración del plugin, el motor de Elgg nos guardará solito los valores al pulsar en en el botón submit "save", para obtener el valor del input tenemos que llamar a la función get_plugin_setting('nombre_input','nombre_plugin') que nos devuelve el valor.
Tened en cuenta que Elgg usa muchos automatismos, por ejemplo sólo con crear un fichero con el mismo nombre del plugin dentro del directorio settings de mod, ya tenéis hecho un gestor de opciones para vuestra contribución, son cosas como estas las que la comunidad agradece tanto, si echáis un vistazo a los foros veréis de lo que hablo, un saludo
Esta es una aplicación multilenguaje del año 2007 con zenphp. Se incluye un administrador interno con capacidad para subir ficheros e imágenes asociados a los inmuebles así como enviar direcciones de youtube para insertar conjuntamente con la descripción de aquellos.
Las cabeceras se pueden cambiar por cada entrada de inmueble de cada categoría, además ,las plantillas contienen un gestor de imágenes con las que se construye una galería con fotografías dentro de la página de cada inmueble…
Las plantillas XHTML + CSS se crearon por Agencia Q4 en el 2007.
En el año 2007 se realizó la programación de esta web se hizo con el prototipo 0.1.2.7 de zenphp, las plantillas XHTML + CSS son validadas por la herramienta de la W3C.
Mediante la ayuda de la administración interna es posible editar el contenido de la base de datos que se muestra en el cliente.
Se realizan validaciones para formularios en AJAX, en cuanto a la administración, además se permite la creación rápida de categorías para platos, y otros parámetros avanzados, etc.
Las plantillas XHTML + CSS se crearon por Agencia Q4 en el 2007.
Uno de los prototipos del framework zen php más avanzados de los años 2007 a 2008 fué desarrollado mientras trabajaba en Agencia Q4, dónde se realizó el diseño de la web (la plantilla XHTML+CSS) mostrada en el vídeo.
Técnicamente: en esta aplicación web se rellena el contenido de las plantillas usando una estructura de clases embebida en una clase principal, es decir, toda la aplicación es un único objeto con referencias a cada parte.
Las plantillas fueron mejoradas usando JQuery para las operaciones de administración con AJAX y validaciones de formularios, animaciones, etc.
Se utilizan las sesiones de usuario para mantener los datos, al enviarse un formulario de reserva se avisa al encargado de los apartamentos y puede ver dicha información de reserva a través de un enlace en el e-mail enviado automáticamente que va directamente a la administración permitiendo realizar las reservas oportunas en el apartamento correspondiente a la reserva.