Portal AJAX con el CMS PHP CodeIgniter y ExtJS

Recientemente he tenido que revisar un portal realizado con el gestor de contenidos ( CMS ) y framework PHP: CodeIgniter, como base y ExtJS como framework JavaScript para proporcionar los servicios de datos por medio del prototipo JSON. Dividiré el análisis en tres partes: Framework JavaScript, Base de datos y Aplicaciones PHP.

Framework JavaScript: Ext JS

Había encontrado algunos problemas, por ejemplo, si entramos en la web con un dominio sin las tres uves dobles, al estar configurado para el dominio con ellas, los ficheros fuente no eran bien referenciados y había errores por todas partes. Estos bugs se corrigieron fácilmente, pero hay que entender o bien por experiencia, por intuición o por inteligencia, de dónde vienen dichos problemas para poder solucionarlos.

El sistema a analizar tiene un directorio privado, sin embargo se ha de crear una lógica de roles de usuario y ficheros de acceso restringido o bien con PHP o bien con .htaccess para que ningún usuario no autorizado a una zona pueda acceder a la información privada que reside en regiones que no le pertenecen.

El primer error que encontré en el diseño de la aplicación no

estaba en la base de datos, ya que el diseño de entidad relación está correcto, dentro de lo que cabe , y he visto verdaderas barbaridades por ahí…como decía, el primer error es la propia interfaz de usuario, mirad este vídeo:

Comentarios:

Para empezar apenas hay espacio en la ventana al no poder quitarnos de encima los componentes que estorban para rellenar datos, hace falta añadir controles con los que ocultar las zonas laterales, como se hace con la zona inferior. Los botones de menú no se ocultan al pinchar sobre una opción y no se muestran mensajes de “cargando” ni información pertinente, de hecho si ocurre algún error este es ininteligible. El chat no funcionaba, aún así se está sincronizando contínuamente por lo que el ancho de banda que consume es considerable. Internamente no hay una verdadera lógica de programación para los roles de administrador representada en JavaScript, es decir, se mezclan los prototipos de todos los usuarios:usuario invitado, cliente, admin,etc. por lo que cualquier usuario que conociera las url o fuera un poco inteligente podría encontrar un mecanismo de operar con la base de datos de la web usando la ingeniería inversa y consultas en los scripts de JSON que además ya vienen en ficheros .js.

Más allá de mi opinión

Sobre si la decisión de usar Ext JS u otro framework JavaScript como JQuery la dejo a elección del programador porque realmente depende de cómo de cómodo te sientas escrbiendo las piezas del puzzle del portal, en este caso está bastante bien porque se utiliza Firebug para depurar PHP con una consola de estado de Ext JS. Aunque es un poco raro mezclar opensource con freesource, es una buena manera de construir un portal complejo, eso sí, siempre que tengamos claro qué es lo que queremos construir…

Un ejemplo de implementación

Veamos un ejemplo de cómo por medio de una vista del modelo MVC de CodeIgniter, construimos contenido JavaScript para alimentar una acción lanzada desde el portal, la bienvenida:
var Center = Ext.extend(Ext.util.Observable, {
constructor	: function(ui) {
this.ui = ui;
 
this.panel = new Ext.TabPanel({
	title		: 'Center',
        region		: 'center',
	activeTab	: 0,
	autoDestroy	: false,
	items: [
	{
	  title:'Bienvenido',
	  closable	: false,
	  bodyStyle	:'font-family:sans-serif;font-size:12px;',
	  html		:'[contenido]'
    }]
});
}
});

En [contenido] debemos colocar el contenido del componente, por ejemplo, un iframe o cualquier otro elemento html que queramos…

Por ejemplo, para añadir  una pestaña con lo que se debe mostrar de un cliente una opción es la siguiente:

MisClientes = Ext.extend(Ext.Panel,{
    // Prototype Defaults
    propA: 1,
	title: 'Mis Clientes',
	closable	: true,
	iconCls: 'icon-mis-clientes-tab',
 
    initComponent: function(){
        // Called during component initialization
this.fields =[
{name:'cliente', type:'string'},
{name:'nombre', type:'string'},
{name:'email', type:'string'}
];
this.storeGrid = new Ext.data.Store({
 reader:new Ext.data.JsonReader({
  idProperty:'cliente',
  totalProperty:'totalCount',
  root:'rows',
  fields: this.fields
 }),
proxy:new Ext.data.HttpProxy(
 {url: BASE_URL +
  'asignarEntrenador/load_clientes_asig'}),
 baseParams:{entrenador:USER_LOGGED},
 remoteSort:true
});
//...etc.

De esta forma hemos encapsulado toda la información de un cliente junto con los widgets que lo representan ,en un único objeto, sin embargo todo el trabajo no acaba ahí, hay que escribir también los prototipos de respuesta para cada una de las acciones, que devolverán otros widgets, elementos de sincronización, alimentadores de datos o datastores, etc. A partir de aquí hay que sumergirse en el mundo del framework Ext JS, y…
Para terminar con el análisis de la sección del framework JavaScript, las plantillas que este utiliza se han guardado separadas del motor PHP (framework CodeIgniter), esto es buena idea porque se puede actualizar fácilmente y además podríamos crear un subdominio para aligerar la carga de la web de forma que realizara las peticiones de todo el contenido JS en paralelo desde el navegador.

Base de datos

Hablando de la base de datos, como había comentado antes, no está nada mal, aquí vemos el diagrama de entidad/relación, los usuarios son la tabla principal del sistema y alrededor de ella se construye todo el conjunto de entidades que abordan las necesidades del cliente, el administrador ,etc.

Correcciones a aplicar sobre la base de datos: se debe modificar el campo usuario de la tabla de usuarios para que sea único, algunos tipos de datos son demasiado grandes para la información que almacenan, hay que tener en cuenta que cuando el número de usuarios crece y con esto también los datos asociados, la sinergía de nuestro servidor de base de datos depende tanto del número de transacciones como del volumen de estas y si estamos usando un framework que realiza una petición de todos los datos de un usuario para mostrarlos con datos asociados por cada prototipo de entidad, el volumen de estos datos genera un considerable tamaño de ancho de banda que puede ralentizar la aplicación. Para esto se construyen consultas que se guardan como vistas y otras consultas avanzadas como las que se pueden realizar con PL/SQL.

En principio la base de datos no necesitaba más cambios, sólo quedaba analizar si estaba preparada para la expansión, es decir, si era escalable, para probarlo, me ví en la tesitura de añadir una tabla que almacenara información relacionada con archivos compartidos entre usuarios de distintos privilegios, y en este caso no tuve ningún problema con la base de datos sino con el siguiente punto ,ya que la lógica de programación no estaba terminada, no había diferenciación fuerte entre roles y aquí fué donde me llevé la gran sorpresa de toda la jerarquía.

Framework PHP : CodeIgniter

El lector seguramente ,como programador sabrá que los tipados fuertes (objetos) siempre son adecuados para embeber información de un usuario, de modo que con una simple lectura de una propiedad de la instancia de la clase usuario->tipo sabremos qué tipo de usuario es…claro, la cosa se complica al tener que replicar la información en un framework como Ext JS, sabemos que podemos encriptar la información pero finalmente,para acometer una acción delicada debemos realizar la comprobación del nivel de privilegios de un usuario por duplicado: en el framework JS y en el framework PHP.

Llegados al punto en que la jerarquía MVC se abría ante mí, todo parecía el paraíso, hay modelos,

class Usuarios extends Model {
    public function __construct()
    {
        parent::Model(); // Call the Model constructor
		$this->table_usuarios = 'usuarios';
		$this->table_usuarios_tipo = 'usuarios_tipo';
		$this->table_session = 'dasm_sessions';
		//$this->load->library('firephp');
    }
 
	//TODO: Comprobar que es un admin
	function crear(){
//etc.

qué es eso “TODO: Comprobar que es un admin”?…sigamos analizando, hay controladores…bien!

class User extends Controller {
 
    public function __construct()
    {
        parent::Controller();
		if (function_exists('force_ssl')) force_ssl();
		$this->load->library('session'); 
 //iniciar libreria de sesiones
		$this->load->library('firephp'); //FIREBUG
		$this->firephp->log("force shhl");
    }
	public function index(){
		$this->login();
	}
 
    public function login()
    {
        if ($this->my_usession->logged_in)
        {
	 $this->firephp->log("login");
//....

es un poco extraño, -me digo para mí- , ahora es todo coser y cantar, pero no…me parece que el programador se acaba de ventilar toda la jerarquía de roles…además, no hay vistas asociadas,ni controladores en los hooks de C.I., pánico…todas las acciones se realizan por real decreto de…llamadas incoherentes dentro de ficheros javascript?…ok, he muerto, ahora he de renacer a la realidad…¿cómo arreglaríais este desastre organizativo?,

Opción básica A: operar sobre la chapuza a sabiendas de que cada vez se enredará más y más el código

Opción B sólo para los valientes: intentar arreglar toda la jerarquía de clases, añadir los hooks, la lógica de roles y rezar para que no haya ninguna incoherencia…en peores batallas hemos estado

Opción C: la gran elegida por el público y aclamada por todos los directores de proyecto solidarios con la causa del programador medio : rehacer el sistema, esta vez BIEN HECHO.

Conclusiones: ¿Cómo no habría sido un fracaso este proyecto antes de llegar a mis manos?

  • Empezando por el diseño del wireframe completo: diseñar la interfaz de usuario aplicación
  • Analizando las tareas a realizar con diagramas de casos de uso donde se vean reflejadas las acciones de cada rol de usuario
  • Construyendo el diagrama de clases en UML o en papel, me da igual pero dibujar, pintad, y luego desarrollar, eso es lo primero, proyectar lo que queremos , si queremos un pato proyectaremos un fantástico sistema de patos y eso es lo que obtendremos, si no sabemos lo que queremos, lo más probable es que el patito feo odiado por toda la familia tampoco lo quiera pagar el cliente
Y quizás, usar otra tecnología…¿Google? :’D

Introducción al IDE de XCode, Objective C e iOS

Curso de creación de aplicaciones de iOS

Hardware y Software que “nos exigen”

  • OSX (Snow Leopard al menos) actualizado a la última versión, para poder instalar el IDE de la manzanita. Nos quieren obligar a comprarnos un Mac, peeero, también podéis instalaros el VMWare Fusion  en un PC (o el VMWare normal pero sin soporte OpenGL), u Oracle VM VirtualBox sobre Windows o GNU/Linux y descargar una imagen de OSX de la red para este software-emulador, e incluso…crearos un Hackintosh, que no es muy caro y están de moda jeje
  • XCode 4 + iPhone SDK: podéis descargarlo de Internet si no tenéis dinero para la licencia de developer, aunque si queréis publicar pronto una aplicación podéis daros de alta en el programa de desarrolladores de la empresa, pagando claro!…
  • iPhone/iPad/iPod: pues hombre, estaría bien  tenerlo para poder probar lo que escribamos, ya que el simulador (no es un emulador!) que trae el IDE se comporta de manera algo distinta a como debería ser…pero bueno, para empezar tampoco vamos a tirar la casa por la ventana jeje Si tienes un dispositivo intenta instalarte el AppWizard para el siguiente paso -no te diré como conseguirlo-

Hardware de los dispositivos iOS

  • El iPhone 4 tiene una resolución de pantalla de 960×640 a 326 ppi.
  • El iPhone 3 tiene una resolución de 480×320 píxels
  • La resolución del iPad es de 1024×768 a 132 ppi

Habilidades que necesitamos para programar aplicaciones de iOS

  • Programar en Objective C: programar aplicaciones de iPhone en XCode es, básicamente, empezar a conocer cómo funciona Objective C y cómo asociar los objetos del Interface Builder a nuestro código. Para eso existen cientos de tutoriales, algunos más famosos que otros como “Masters of the Void“, pero lo mejor es seguir un libro gratuito de la propia empresa (en el apartado de desarrolladores) o ir a una biblioteca y pillarse libros como Objective C for dummies, iPhone application development for dummies, y luego algo más serio como iOs4 Programming Cookbook de O’Reilly, ya que contienen multitud de ejemplos y trucos para desarrollar todo lo que deseemos/necesitemos.
  • Hay un libro de la web de MacProgramadores bastante bueno sobre Objective C con especial énfasis en su origen (NeXT) y XCode, lo han borrado de la web, pero seguro que lo encontráis…

Introducción a XCode e iOS4 SDK

Conceptos básicos:

XCode

  • Xcode es el IDE que nos ofrece Apple para desarrollar aplicaciones de iOS.
  • El SDK (Software Development Kit) incorpora herramientas para el desarrollo (entre ellas, el simulador de iPhone/iPad).
  • El lenguaje de programación es Objective-C
  • Simulador de iOS: Permite simular tanto iPhone como iPad en nuestro Mac.
  • Interface Builder: Editor visual para diseñar interfaces de usuario para nuestras aplicaciones.
  • Instruments: Herramienta de análisis que nos ayuda a optimizar y monitorizar la aplicación

Sistema Operativo iOS

  • El Sistema Operativo de los dispositivos de Apple (iOS), está formado por un conjunto de capas, que conforman el conjunto de servicios ofrecidos por el dispositivo. Arquitectura:
  • Cada capa de la arquitectura está compuesta por un conjunto de frameworks
  • La capa Core OS es la base del sistema operativo. Se encarga de realizar la gestión de memoria, el sistema de ficheros, conexión a la red y procesos que interactúan con el hardware
  • Core Services nos permite el acceso a los servicios básicos, tales como la agenda, el acceso a la base de datos, preferencias, conexión a servidores y procesamiento de URLs, etc…
  • La capa Media nos permite la ejecución de tareas multimedia. Entre ella el acceso al Audio, OpenGL, Imágenes y PDF, Animaciones, etc…
  • Cocoa Touch nos permite acceder al acelerómetro, los eventos y controles táctiles, la jerarquía de vistas, alertas, etc…gestiona la interacción visual con el usuario
  • Novedades de iOS4:
  • Multitarea: mientras ejecutamos una aplicación, al pulsar el botón “home” no se cierra sino que pasa a segundo plano, pueden continuar ejecutándose o pueden suspenderse
  • Notificaciones Locales: completa el sistema de notificaciones push (desde un servidor remoto que nosotros mismos podemos crear)
  • Core Motion: conjunto de interfaces para acceder a toda la información basada en el movimiento (giroscopio ,motion-based)
  • Data protection: sistema integrado de encriptación
  • Soporte para pantalla de alta resolución (adaptación a la antigua)

Frameworks

  • Un framework es un conjunto de librerías que nos permite añadir una funcionalidad concreta a nuestra aplicación
  • Por defecto, cuando creamos un proyecto, tenemos los frameworks esenciales para el funcionamiento básico
  • Por ejemplo, para usar bases de datos SQLite usaremos su framework, simplemente con copiar el directorio descargado de su web, aunque en la versión de XCode4 ya viene integrado, también haremos lo mismo con Cocos2D
  • Cocoa Touch: conjunto de frameworks orientados a objetos que permiten el desarrollo de aplicaciones nativas para iOS

Crear una aplicación

Pasos

  1. Abrir XCode y crear un proyecto
  2. Diseñar la interfaz de usuario
  3. Escribir el código asociado de la aplicación
  4. Compilar, ejecutar y probar (vuelta al paso 2)
  5. Medir y ajustar el rendimiento de la aplicación
  6. Producir y publicar la aplicación

Tipos de proyecto

  • Cocos 2d: para crear juegos (necesita el framework Cocos2D),lo veremos en otro curso, de programación de videojuegos para iPhone
  • Navigation-based : presentan la información de forma jerárquica usando múltiples vistas (diseño de pantallas)
  • Open GL : igual que cocos, además de juegos podemos crear cualquier tipo de aplicación que represente imágenes, animaciones o gráficos 3D
  • Split View-based : Aplicaciones enfocadas para iPad que muestran más de una vista en la pantalla al mismo tiempo (un control listado y una vista detalle de elementos normalmente)
  • Tab Bar : presentan una interfaz de “radio” que permite al usuario elegir entre varias opciones
  • Utility : aplicaciones que presentan una vista principal y permiten que el usuario acceda a otra vista para realizar personalizaciones básicas
  • View-based : una vista simple para implementar la interfaz
  • Window-based : plantilla universal (cualquier dispositivo con iOS) que sirve de punto de partida con un delegado y una ventana. Útil para aplicaciones con jerarquía propia

Recordar que no todos los tipos de aplicaciones pueden ser universales (para cualquier iDevice) y las que lo son tienen diferentes diseños de interfaces de usuario en subdirectorios con su nombre.

Interfaz de XCode

XCode4: editor en una ventana

XCode4: Interface Builder

XCode4: Git integrado

Tipos de ficheros de un proyecto

  • Info.plist: como todos los plist, es un XML (introducido por NeXT) constituído de propiedades de configuración en UTF-8
  • Ficheros.h: declaraciones de interfaces ,clases y atributos
  • Ficheros.m: implementación de clases y métodos definididos en los .h (aunque no necesariamente requieren un .h)
  • Ficheros .pch: cabeceras precompiladas que se añaden a las clases
  • Ficheros de objetivo: resultado de la compilación de un conjunto de ficheros de código, puede ser una librería o una aplicación. Un conjunto de objetivos forman un producto. Lo utilizaremos para publicar una aplicación en la tienda

Perfiles de compilación

  • Depuración: incluye la opción de depuración al compilar con gcc, es más lenta pero encuentra errores lógicos. Se puede depurar en el editor de texto, mini-depurador, depurador y en la consola [(gdb)]. Opción: GCC_GENERATE_DEBUGGING_SYMBOLS. Podemos usar breakpoints.
    Mientras el programa está siendo depurado podemos modificarlo (como pasaba en VisualBasic y otros lenguajes! :D) : cambiar el nº y tipo de argumentos de una función o método que esté en la pila,el tipo del valor de retorno o el nombre de una  función o método también en la pila, así como cambiar el tipo de las variables estáticas, un fichero NIB, añadir clases o cambiar sus métodos…
    Leer más >
  • Lanzamiento: mayor rendimiento de la app, tamaño de objeto final compilado menor.
  • Distribución: como el anterior pero necesita un certificado o firma de Distribución válida (con apple hemos topado xD, aunque podemos arreglar esto con algún que otro truco de Cydia…). Se añade meta-información necesaria para ser validada en la tienda.

Introducción a Objective C

¿Qué es?

  • Pequeño set de extensiones de ANSI C
  • Sus añadidos a C están basados en Smalltalk, uno de los primeros lenguajes orientados a objetos
  • Diseñado para dotar a C de toda la potencia de la orientación a objetos

Clases

  • Sintáxis normal de creación de clases: interfaz (.h) + implentación (.m)
  • Ejemplo de clase Persona.h:
    @interface Persona : NSObject {
    NSString *nombre;
    NSString *apellidos;
    }
    -(NSString*) nombre;
    -(NSString*) apellidos;-(void) setNombre: (NSString *) _Nombre;
    -(void) setApellidos: (NSString *) _Apellidos;
     
    +(NSString *) soyMetodoEstatico: (NSString *)  mensaje;
    @end

    Ejemplo de clase Persona.m:

    #import "Persona.h"
    @implementation Persona
    -(NSString*) nombre {
    return self.nombre;
    }
    -(NSString*) apellidos {
    return self.apellidos;
    }
    -(void) setNombre: (NSString *) _Nombre {
    self.nombre = _Nombre;
    }
    -(void) setApellidos: (NSString *) _Apellidos{
    self.apellidos = _Apellidos;
    }
    +(NSString) soyMetodoEstatico: (NSString *) mensaje{
    return mensaje;
    }
    @end
  • Ejempo de función que toma datos de la clase padre de la que hereda:
    - (id) init {
    if ( self = [super init] ) {
    [self setNombre:@"nombre por defecto"];
    [self setApellidos:@"apellidos por defecto"];
    }
     
    return self;
    }

    self es la propia instancia del objeto y super es la clase de la que hereda

  • Declaración de un método:
  • A través del corchete accedemos a un objeto, que es el primer parámetro, el segundo es la llamada al método, es como hacer
    $this->método en PHP , o puntero_a_clase -> método , en C / C++,Java.
    Por ejemplo , un método sin entrada

    [object method];

    Con entrada:

    [object methodWithInput:input];

    Con salida:

    output = [object methodWithOutput];

    Con entrada y salida:

    output = [object methodWithInputAndOutput:input];
  • Recordar que si queremos especificar una función con varios parámetros se ponen dos nombres, uno para el nombre clave de llamada y otro para el nombre interno del parámetro, el primer nombre de nombre clave no se pone, ejemplo:
    -(void) miFuncion: (int)parametro1 nombre1: (bool) parametro2 nombre3:(NSString*) parametro3;
    a esta función accedemos así, ejemplo con datos:
    [miObjeto miFuncion:7 nombre1:true nombre3: @”cadena”
    Fijaros que una cadena siempre se precede de una arroba.
  • Propiedades de una clase: (@property)
    permiten generar automáticamente métodos de acceso para los atributos de una clase, podemos sobrecargar los métodos setter & getter si no usamos las especificaciones por defecto de una propiedad, para saber cuál nos conviene primero debemos ver la gestión de memoria. Por defecto, el setter se añade automática a la propiedad definida como setNombre_variable (set+UCase(nombre_variable)), y el getter es el nombre de la variable atributo tal cual, en Persona.h el setter es setNombre y el getter nombre. Fácil.
    Para que podamos usar las propiedades es obligatorio inicializarlas con @synthesize en Persona.m (la implementación de la clase),este genera los setters y getters automáticamente. Una vez hecho además podemos especificar en esta línea de sintetización el nombre local del acceso o accesser, algo como @synthesize nombre = _nombre_local;
  • Ver más >

Gestión de memoria!: de lo más importante en Objective C

  • Con el método dealloc liberamos memoria utilizada en las instancias de nuestras clases, lo vamos a sobrecargar para hacer “release” de todas las instancias de objetos que hayamos creado
  • Se debe liberar por completo el propio objeto también ,con [super dealloc] .
  • Debemos liberar las variables de tipado fuerte
  • Para aprovechar la memoria tenemos que crear nuestro propio “recolector de basura”, algunos ven esto como muy buena idea y otros no son partícipes de que el lenguaje no tenga las bondades de Java…
  • Para gestionar qué variables están siendo utilizadas en memoria, tenemos lo que se llama el “contador de referencia” de Objective C, sólo tenemos que especificar qué hacer con las variables al asignarlas, crearlas, copiarlas, pasarlas por parámetro, etc. y la ejecución del programa hace el resto.
  • Con alloc inicializamos memoria en función del tipo o clase de una variable, por ejemplo, cuando declaramos una variable de tipo NSNumber con una instrucción como esta:
    NSNumber *number = [[NSNumberalloc initWithFloat:8.75;
    lo que pasa internamente es que el contador de referencias se pone a 1.
  • Con retain aumentamos el contador de referencias en uno, por ejemplo si deseamos liberar en un contexto la variable pero no queremos que se pierda la variable porque se usa en otro contexto, por ejemplo:
    -(
    void) setNombre: (NSString *) _Nombre {
    [self.nombre
    autorelease;
    self.nombre = [_Nombre
    retain;
    }
    Usando autorelease se libera al objeto de manera diferida, es decir, es posible usar la variable de la primera línea durante un tiempo más, le dice al compilador que la variable self.nombre se decremente al salir del contexto de la clase de la función setNombre, después le asigna un nuevo valor, el del parámetro, pero a este le dice que lo retenga aunque se borre fuera, para que sea gestionado desde la clase.
  • Con release se decrementa el contador en una unidad, si tiene valor 1 ,se borra la variable, es decir, le decimos al sistema que no la necesitamos y éste llama a dealloc automáticamente (primer punto)
  • Ojo entonces, si por ejemplo creamos un método en una clase para asignar un valor y hacemos que use release para luego hacer retain con el nuevo valor que le pasamos, siendo este no una variable sino una llamada de una función, algo así:
    ________
    – (
    void) setNombre: (NSString*) _Nombre {
    [self.nombre
    release;
    self.nombre = [_Nombre
    retain;
    }


    persona
    * ego = [[personaalloc init];

    [ego
    setNombre:[ego nombre];
    ________
    al llamar a la función setNombre, primero se libera el objeto self.nombre antes de retenerlo, por lo que ya no hay espacio reservado en memoria para esta variable y aquella pasa a estado incoherente ya que el valor que le hemos pasado es precisamente el que hemos liberado, para solucionarlo ponemos autorelease en lugar de release.
  • Ahora podremos saber qué tipo de gestión de memoria asignarle a una propiedad, por ejemplo para el nombre en nuestra clase Persona.h:
    @property (retain) NSString* nombre;
    al poner retain hemos declarado que el setter (función como setNombre pero automática) debe hacer retain sobre el valor de entrada. Pero podemos especificar con setter=setNombre nuestra propia función ;)
  • A veces tenemos que tener cuidado con lo que liberamos de la memoria, no podemos dejar todo en autorelease porque al pasar la referencia de una variable entre funciones es posible que se libere antes de tiempo, sin embargo de esto nos daremos cuenta cuando el simulador haga CRASH! jaja

Variables

  • Tipado débil: int, bool, float, etc.
  • Tipado fuerte: objetos como NSString, NSNumber, etc.
  • ejemplos de métodos con tipos distintos:
    - (int) multiplica: (int)a por:(int)b {
    return a * b;
    }
     
    - (NSString *) cadenaResultado: (int)resultado {
    NSString *res = [NSString stringWithFormat:@"El resultado es: %d", resultado];
     
    return res;
    }
     
    int resultado = [self multiplica:2 por:3];
    NSString *cadena = [self cadenaResultado:resultado];
    NSLog(@"%@", cadena); //devuelve 6
  • Un protocolo (@protocol) permite que la lista de métodos que contienen se puedan implementar por cualquier clase, puede especificarse al crear una clase en su definición de la clase que hereda de otra…
    @protocol MyProtocol
    - (void)requiredMethod;
    @optional
    - (void)anOptionalMethod;
    - (void)anotherOptionalMethod;
    @required
    - (void)anotherRequiredMethod;
    @end
     
    @interface ClassName : ItsSuperclass < protocol list >
  • Otro método para depurar es usar el log, la función NSLog(cadena) usa el mismo formato que un printf, recordar el formato:

    NSLog(@”La fecha y hora actual es %@”, [NSDatedate );

XCode Organizer

  • Una vez creada la aplicación, si queremos usarla en un iDevice, tenemos que desplegarla (necesita certificado), conectar el dispositivo por USB y probar! Pero también podemos usar el simulador ,aunque no refleja el comportamiento exacto (real) de la aplicación si que sabremos si funciona o no :)

Consejos

Diseñar como un ingeniero y producir como un artista: echad mano de vuestro amigo el arquitecto de información para encontrar la mejor manera para guardar los datos,… no es lo mismo una base de datos en SQLite que un conjunto de ficheros XML.

  • Hay que conocer el flujo de la información en el sistema de aplicaciones, por ejemplo un sistema de etiquetas debe ser recurrente en cuanto a que hay tags que se repiten, la forma óptima de hacer esto es como lo hace WordPress o algunas aplicaciones web si lo prefieres. Debemos consultar a nuestro amigo experto en marketing para el nombre del programa, así será el dominio para publicarlo, también nos aconseja qué tipo de características son viables en cuanto a lo que el público demanda y nos da su perspectiva como experto lo bonito, barato y bueno. Efectivamente, necesitamos conocer cómo construir diagramas pero no son indispensables, aunque sería ideal diseñar previamente la app con UML
  • Beta tester: antes de empezar si quiera a pensar en querer programar algo para iOS ,lo primero que debemos hacer es conocer los dispositivos, el iOS y OSX, todos los widgets del sistema operativo, así que al menos tenemos que haber probado todas las aplicaciones antes mencionadas, aunque sea en el ifón de un amigo, no vale haberlo visto en vídeo, tenemos que tocar la esencia de la magia de esta tecnología para sentir qué queremos hacer realmente.

Otros tutoriales para conocer el IDE XCode 3: nos sirve para empezar.

Ahora que conocemos el IDE de la mano de Noemi gracias a sus tutoriales de Youtube, vamos a seguir un poco más adelante, tenemos la ayuda necesitamos aquí:

Ejercicios (Deberes :)

  1. Ejercicio 1: crear un proyecto tipo “View-based”, crear una clase Persona y otra clase Usuario, establecer propiedades en las clases asociadas a sus atributos, una clase Usuario debe tener un atributo que sea una clase Persona.
  2. Ejercicio 2: Crear un NSArray e inicializarlo con clases NSNumber, luego mostrarlo con NSLog
  3. Ejercicio 3: Crear un NSMutableArray e inicializarlo con clases Persona, añadir  a dicha clase la función (sobrecargada) description para que NSLog pueda mostrar el contenido de todos sus atributos

Para corregirlo podéis enviármelo con el formulario de contacto.

<< Volver al curso de programación de aplicaciones de iOS

Siguiente: conectar interfaz con el código

Programación rápida y avanzada con SilverStripe

SilverStripe es un gestor de contenidos (o CMS: Content Managed System) avanzado de código abierto, especialmente diseñado para que los diseñadores puedan trabajar en colaboración directa con los programadores funcionando independientemente el uno del otro pero relacionados por mecanismos automáticos simplificados que pueden extenderse ilimitadamente.
Podemos probar una demo del producto aquí y descargarlo aquí.

Está escrito en lenguaje PHP y es compatible con servidores IIS, Apache, etc.

A mi modo de ver las cosas me resulta muy parecido a Django, ya que hace uso del patrón de ingeniería del software: MVC (modelo-vista-controlador)

y los elementos de la base de datos y de la administración se generan automáticamente a partir del código, de hecho existe un script que lee las clases que hemos escrito en búsqueda de la variable de base de datos donde se especifican los campos y sus tipos, de forma que actualiza la estructura de aquella para que se puedan realizar altas/bajas/modificaciones con sólo añadir una línea en el código de la parte de administración de una sección del contenido de una página, después se crea una plantilla y se utilizan dichos campos con sólo llamar a la variable con el nombre del campo especificado.

Para conocer los entresijos de la programación con SilverStripe, los creadores han dispuesto un subdominio de ayuda con tutoriales que van desde las tareas de código más simples hasta las más avanzadas, por ejemplo, en mi caso he utilizado este manual para crear una homepage distinta a la que trae por defecto y ha funcionado a la primera…una gozada,podemos crear todos los tipos de páginas que queramos con sus secciones, por ejemplo una sección de productos sería una página donde sus elementos de base de datos son un conjunto…lo que se llama un data object (que hereda de sitetree) generando un data collation, aquí en la imagen vemos una sección de noticias con artículos donde se define una clase contenedora de artículos a la que se le permite tener “hijos”, otra clase para los artículos y se relacionan entre sí

Como características curiosas, trae un gestor de comentarios para cada página y un generador de RSS…, pero lo más curioso es que el CMS se divide en 6 partes bien diferenciadas o directorios principales:

  1. en assets se guardan los ficheros subidos,
  2. en cms se encuentra el backend o administrador de contenidos,
  3. en mysite se colocarían nuestras clases, código PHP y JavaScript
  4. en sapphire podemos encontrar el frontend o cliente
  5. en themes se encuentran las plantillas XHTML+CSS, la caché ,etc.
  6. en el directorio principal, cualquiera de los otros directorios que no sea uno de los anteriores ,se trata de un plugin, módulo o extensión del cms que especifica las acciones tanto para el frontend como para el backend

Código

Este trozo de código especifica la clase para los artículos de una sección de noticias:

class ArticlePage extends Page {
static $db = array(
'Date' => 'Date',
'Author' => 'Text'
);
static $has_one = array(
);
 
function getCMSFields() {
$fields = parent::getCMSFields();
 
$fields->addFieldToTab('Root.Content.Main', new DateField('Date'), 'Content');
$fields->addFieldToTab('Root.Content.Main', new TextField('Author'), 'Content');
 
return $fields;
 
}
}
 
class ArticlePage_Controller extends Page_Controller {
 
}

El modelo ArticlePage hereda de Page y tiene un controlador ,pero además necesita un decorador, en el caso en que no se especifique se utiliza el asociado al padre Page. (Ver listado de tipos de datos)

Para la gestión de los campos en la administración se utiliza la función getCMSFields() heredada de Page y se le añaden nuevos campos, aparecería algo así como resultado:

Veamos un ejemplo sencillo de código fuente de GoogleSiteMaps incluído en la versión 2.4.1 que es probado aparece el siguiente trozo de código:

 
class GoogleSitemapDecorator extends SiteTreeDecorator {
 
function extraStatics() {
return array(
'db' => array(
"Priority" => "Varchar(5)",
)
);
}
//...

esta clase se usa para “decorar” ,es decir, para especificar al controlador con qué vista va a pintar los datos del modelo de datos tanto para el front como para el backend, además se está especificando un array para la generación de los campos de la base de datos desde el exterior…

Para tener una introducción más completa, aquí hay un vídeo que os puede interesar:

SilverStripe 2.4 Site Editing Overview from SilverStripe on Vimeo.

Embeber clases de C++ como una extensión de PHP usando Zend

Vamos a ir un poco más lejos que la última vez cuando analizábamos la gran ventaja de usar el lenguaje C++ frente a PHP, por su potencia al estar compilado para la máquina, en lugar de interpretado como PHP, sobre todo a la hora de usar algoritmos que requieren de un tiempo de ejecución mayor, a pesar de que, su orden de ejecución no es muy elevado; al cambiar de tecnología se nota demasiado.

En este caso vamos a echar mano del framework de la empresa Zend que casualmente se utiliza en Magento como base y alguna otra tienda ( soloprecios.es ) también,… este artículo de la zona de programadores de Zend Framework, nos recomienda primero echar un vistazo al manual para escribir una extensión…, en este punto, quizás , os decantéis por olvidaros de Zend y queráis echar un vistazo a la herramienta que usan en FacebookHiHop, sinceramente os recomiendo leer  los informes de las unidades de prueba realizadas por Sebastian Bergmann primero.

En el artículo de paulosman, se explica cómo configurar el makefile (para compilar C++) para que se incluya la extensión de PECL con phpize , además es tan apañao que incluye incluso una macro para hacer la llamada a la función ZEND_GET_MODULE() que necesita el framework para asociar la clase con PHP, tras realizar estos pasos podemos usar :

 php -d"extension=nombre_de_mi_extension.so" -m

para añadir la extensión recién compilada (tras usar phpize y make) a Apache u otro servidor (con Zend) ,ahora que tenemos el esqueleto básico de dicha extensión cargada en el servidor, el sistema de construcción de PHP sabe que tiene que compilar las clases C++ (definidas e implementadas fuera de la extensión) que se sincronizarán por medio de los objetos en C++ de Zend y la función externa ZEND_GET_MODULE(nombre_de_mi_extension)

¿Alguna duda?, aquí estamos…

Catálogo de papelería – Flash + XML + PHP + MySQL

La aplicación web del proyecto hace uso de la tecnología Flash con XML y PHP + MySQL para crear un catálogo administrable usando el framework zenphp prototipo del 2007-2008 como base de programación. Las diferentes secciones contienen categorías configurables con un editor de texto enriquecido dentro de un gestor de contenidos programado a medida

El diseño XHTML+CSS+FLASH de la página es de Agencia Q4.

Sistema de aplicaciones web multicapa, multidocumento y multidioma

Usar este sistema significa poder elegir la lógica de presentación que deseemos, sin tener que cambiar la lógica de programación. Puedes insertar tantos documentos e imágenes por artículo como quieras, además, en el mismo paquete se incluyen utilidades para insertar en el contenido de estos artículos las imágenes o enlaces que necesitemos como en un blog,relacionados con ficheros locales o remotos que usan las aplicaciones web. El mismo perfil de aplicación es capaz de añadir de forma sencilla tantas categorías y subcategorías como se quiera o eliminarlas para mostrar directamente los artículos de una sección.

Utiliza el framework zenphp del que hemos hablado alguna vez previamente, se conecta con las redes sociales de forma sencilla y el contenido administrable es súper fácil de utilizar, para muestra un vídeo.

La programación de los contenidos se hace a través de un modelo de datos genérico que tiene diferentes controladores y vistas de forma que con la misma tabla sólo se utilizan los campos necesarios por cada tipo de contenido de una sección y una tabla asociada guarda los nombres de las categorías y subcategorías que tienen relación directa con los artículos donde se almacena la información para cada idioma.

En este caso el cliente necesitaba una lógica distinta así como diferentes presentaciones para los mismos contenidos dependiendo de la sección/categoría de modo que los cambios realizados no ocupan apenas unas líneas.

El diseño está realizado por Agencia Q4.

Página 1 de 212
footer
jbelon © | sitemap.xml