martes, 20 de julio de 2010

'La última lección'

Hoy voy a contar un secreto. Pienso en la muerte. En mi muerte. No sabría decir si muchas o pocas veces. Aunque tengo la sensación que es más bien poco. No es cada día, claro. Tampoco puedo decir que sea una vez al mes. Ni cuantas semanas pasan entre dos pensamientos de este tipo. Simplemente pasa. A veces pienso más, a veces menos.

Tampoco sé si es bueno o malo. Simplemente sucede. Estoy ensimismado (¿o sería «enmimismado»?), tal vez sentado en una guagua o cualquier transporte público mirando al exterior por la ventana y, repentinamente, me doy cuenta que estoy pensando en la muerte. En mi muerte.

No me siento triste por ello. Ni angustiado. Tampoco me veo a mí mismo deseando que llegue para acabar con algún sufrimiento oculto y enquistado con el que no he sabido convivir. A estas alturas he aprendido a disfrutar de mí mismo. Y no me siento particularmente feliz pensando en ello. Diría más bien que es un sentimiento aséptico. Simplemente pongo mi muerte en perspectiva. Me dibujo a mí mismo ante la situación y me pregunto si, llegado el momento, podría decir que ha merecido la pena vivir mi vida. ¿Tendría el atrevimiento de llegar a decirle a alguien que me tomara como ejemplo? ¿A mis sobrinos que ahora ya están entrando en esa difícil y hormonada edad que son los 15 años? ¿O habría sido mi vida lo suficientemente interesante como para que los amigos, tal vez los pocos que he ido encontrando y manteniendo durante mi vida, exclamaran con gesto alegre frente a mis cenizas «¡he aquí a un tipo que vivió feliz y murió orgulloso!»?

A veces creo que lloramos a los muertos no porque nos importe realmente la pérdida. Muchas veces sería generoso decir que los conocíamos realmente. Hace poco han muerto algunos familiares, pero poco podría decir de ellos como personas. Nada más allá de la superficie.

Creo que muchas veces los lloramos porque creemos que su vida quedó inacabada y que les faltó las cosas importantes por vivir. O porque nos recuerdan, con su muerte, que nuestras vidas están incompletas. Son como avisos previos antes de la gran cita ¿Tal vez no sea más que nuestra proyección de nuestros miedos por decaer en unas existencias no saciadas? ¿Lloramos por nosotros? ¿O por la consciencia del mal uso que damos al tiempo que nos toca vivir? Nuestras lágrimas son un lamento no por nuestra pérdida, sino de pena por una vida incompleta, banal y que, por desgracia, ya no dispondrá de tiempo para ser corregida. Es lo que a veces creo.

La muerte es inevitable, eso es algo que sé. Que todos sabemos. Pese a que la mayoría de la gente rehuya de ella. Negándola en esa forma obstinada en que se niegan las cosas: evitando pensar en ellas, girando la cabeza. Sin embargo, ser consciente de nuestra caducidad nos puede guiar sobre los pasos que deberíamos dar para conseguir que nuestra propia y fugaz existencia tenga algo de valor. Al menos para nosotros mismos. Y, por mis propias creencias, lo que realmente tiene valor es aquello que también resulta apreciable a las personas que queremos. No hay nada más triste y patético —en mi humilde opinión— que el éxito en solitario.

Así es cómo pienso yo en la muerte. En mi muerte. Como alguien ajeno a mí mismo que me estuviera dando consejos sobre cómo mejorar mi vida para no arrepentirme de no haber vivido. Cosas como «¿es esta la elección que quiero recordar dentro de unos años?»

Vale, puedo resultar estrafalario. Pero si el cubo de la basura o la carretilla se abollan, nadie se compra uno nuevo. Quizá sea porque no usamos el cubo y la carretilla para comunicar nuestro estatus social ni nuestra identidad a los demás. Para Jai y para mí, los coches abollados se convirtieron en una declaración de principios de nuestro matrimonio. No todo necesita arreglarse.

Tal vez tenga algo que ver lo que leí allá por el 2007, a poco de cumplir los 35 años, haciendo calentamientos de cara a la crisis de los cuarenta, escrito de forma genial por el siempre magistral Frikosal [Teología Ficción: La doctrina del perpetuo revivir]. Recomiendo mucho leer a este hombre de prosa ligera, ideas claras, inquietudes infinitas y fotógrafo excepcional. Especial atención merecen las reflexiones de sus entradas de teología recreativa.

En cualquier caso, tampoco me obsesiono demasiado con ello. Aunque los anteriores párrafos puedan dar lugar a creer lo contrario. Duermo poco. La mayor parte del día mi cerebro funciona en pos de temas más prosaicos. Cuando funciona. Pero sé que la muerte sucederá cuando tenga que suceder. Me guste más o menos. Aunque hay quienes creen que la vida es, en realidad, una preparación para la muerte. De hecho, salvo que seas un ateo irredento, entrarás dentro de ese increíblemente inmenso grupo de gente, seas cristiano, musulmán, judío o budista, que creen que la vida es, precisamente, un conjunto arbitrario de sucesos para poner a prueba tu fe y, con ello, aprobar o suspender en el salto a la otra vida. Un examen constante en el que el tiempo lo limita tu existencia corpórea. ¿No resulta curioso que, de una forma u otra, todos obremos dirigidos por la inevitabilidad de la muerte? Al menos a mí sí me lo resulta. Unos movidos por el ansia de recompensa y premio en la otra vida —o enfocándolo a huir del castigo— y otros empecinados por hacer de esta una vida que haya merecido la pena. Y a poder ser perdurar en la memoria de unos pocos un poco más allá de nuestro tiempo.

No costará mucho imaginar que, con este mal de fondo, que algunos considerarán como pensamientos enfermizos, me sintiese inmediata e irrefrenablemente atraído por el libro 'La última lección' [@ Wikipedia] cuando, seducido tanto por su título como por su portada, lo extraje de la estantería de la librería en la que estaba y leí la reseña que traía en su contraportada. A su autor, Randy Pausch [@ Wikipedia], le habían dado seis meses de vida y quería enseñarnos lo importante que es vivir la propia vida. Está muy bien eso de fantasear con los consejos que me daría —o daría a otros—, cuando me llegara la hora, sobre de qué forma sería mejor vivir el tiempo que me/nos ha tocado. Pero ante lo incierto del cuándo, la fuerza de los argumentos se disipa y se pierde en la improbabilidad del tiempo inmediato. Ya se sabe que, en el fondo, nuestro cerebro es incapaz de hacer planes y tener perspectiva auto consciente del día que va tras mañana. Pero ante mí tenía la prosa de alguien que ya conocía el cuándo, por lo que aquello que pudiera decir tendría, además, el valor de la experiencia.

No lo dudé mucho y me lo llevé. Ha estado unos cuantos meses a la espera. Que en el momento de comprarlo me resultara atractivo por su temática no significa que mi mente tuviera otras preferencias a corto plazo. Como decía, la muerte no es tampoco un tema que me obsesione en exceso. Pero como a todo cerdo, le llegó su San Martín, y, en una especie de reinicio de la cola de espera de libros, busqué qué leer a continuación del que acaba de leer y se ubicó como opción inmediata.

El libro cuenta los preparativos y ahonda en los temas tratados en la conferencia que lanzó a la fama de Randy Pausch [Randy Pausch Last Lecture: Achieving Your Childhood Dreams @ YouTube]. Yo no la había visto y desconocía al autor y su fama cuando compré el libro, pero después de leer el libro dediqué un tiempo a ver la conferencia. Si alguien la ha visto y no ha leído el libro, aclarar que el libro apenas aporta mucho más a la historia del protagonista de lo que es la propia conferencia. Aunque son formatos completamente distintos. La prosa del libro rebosa ganas de vivir y vitalidad. Pero también es muchísimo más íntimo. Estás compartiendo pensamientos en privado, casi susurrados, en la intimidad de tu casa. Puedes volver atrás y rumiar otra vez los últimos párrafos especialmente intensos que acabas de leer. Tampoco estás cohibido por cientos de personas que comparten habitáculo contigo. Sin embargo, verlo contar las experiencias en persona es así mismo toda una experiencia. Resulta muy intenso. Choca muchísimo. ¿Cómo es posible que un tipo que sabe que la va a palmar en unos meses derroche tanta energía y tanta cantidad de buen sentido del humor? Te dan unas ganas enormes de tirarte al suelo a hacer flexiones con él. El libro y el vídeo son complementarios y merece la pena dedicarle tiempo a los dos. Aunque, por eso de fantasear con improbables, si tuviera que escoger uno para llevármelo a una isla desierta, optaría por el libro. Como dije, me resulta mucho más íntimo y personal.

   —¿Cuántos hombres hay en el campo de fútbol al mismo tiempo?
   Once por cada equipo, contestamos. Es decir, veintidós.
   —¿Y cuántos tocan la pelota en un momento dado?
   Uno.
   —¡Correcto! Pues nosotros trabajaremos lo que están haciendo los otros veintiuno.

Aunque generalmente no me recreo —ni permeo en exceso— en lo emocional, sí que es cierto que me emociono con facilidad. Después de todo, pese a la cubierta de chocolate blanco y a la armadura de cinismo, tengo mi corazoncito. Confieso que me emocioné, al punto de ojos vidriosos, viendo el anuncio de la abuela premiada con la ONCE [@ YouTube]. Por poner un ejemplo que ahora me viene a la mente de cuán ñoño puedo llegar a ser. Quedarme en ese estado de aflicción al punto de la lágrima me ha pasado pocas veces. La última, con algunos párrafos de 'La última lección'. Es un libro, a mi modo de entender la vida, muy emotivo. Cierto que la prosa es mala, mucho, sintiéndolo francamente por el escritor o por el traductor. Pero la reducida calidad de la prosa no resta puntos a un libro que no busca explotarla como recurso principal, sino como mecanismo para hacer llegar las ideas. En ese aspecto es clara y funcional. Para mi gusto, algunas de las situaciones que cuenta, incluso algunos de los pensamientos que refleja, son sincera y llanamente, magistralmente humanos. Para llorar a moco tendido, si tu educación te lo permite. Son exposiciones magníficas de instantáneas de la vida de alguien que se gana el respeto de la gente por ser, precisamente, un ser humano ejemplar.

El libro ha rozado la categoría de must read. Se ha quedado a las puertas. Principalmente porque me ha resultado especialmente vitalista, que anima a arrimar el hombro, esforzarnos, en dar sentido a nuestra existencia, que empuja a agarrar la vida con ambas manos y que, en esencia, nos pide que no dejemos nunca de soñar ni de ser nosotros mismos. Algo que en estos tiempos de monotonía en la identidad de las personas y de crisis existenciales, además de económicas, es casi una balsa salvavidas. Sin embargo, la estructura de muchos micro capítulos, algunos de apenas un par de páginas, en las que se presenta el libro hace que la lectura resulte desigual, con muchos altibajos. Como el que ve un álbum plagado de instantáneas desordenadas. Algunas con tan poca definición que cuesta identificar los rasgos de la persona. A mi modo de ver, hay vivencias referidas en el libro que resultan puramente redundantes —algunas veces— o carentes de aporte a la fuerza argumental del hilo conductor —la mayoría de las veces—. Vamos, que hay mucha paja y que el libro bien podría haberse quedado en las dos terceras partes sin perder ni un ápice de su carga emocional y existencial, ni de su mensaje sustancialmente humano. En cualquier caso sí que considero que entra dentro de la categoría de los recomendados. Mucho. Por méritos propios y con pleno derecho.

No estiro más la larga entrada de hoy y acabo lanzando una pregunta que aparece en las primeras páginas: «Si tuviéramos que desaparecer mañana, ¿qué querríamos dejar como legado?» Espero que sirva para reflexionar a algunos.

No podemos cambiar las cartas que se nos reparten, pero sí cómo jugamos nuestra mano.

Randy Pausch

domingo, 18 de julio de 2010

El día que Steve Jobs destruyó las relaciones humanas, de rebote se cargó la sociedad y el mundo, y perjudicó seriamente la salud de mi abuela

Hace unos días —en realidad bastante más de unos días— caminaba tranquilo en estado de consumista predispuesto. Ese estado en el que paseas tranquilamente por tiendas y comercios, pero sin una finalidad concreta más allá que curiosear y, eso sí y siempre, con la mano intranquila deseosa de sacar la cartera si la oferta resulta lo suficientemente atractiva.

En tan lamentable estado me acerqué a unos grandes cajones, de esos que ponen en todos los comercios, independientemente de lo que vendan, lleno de películas en formato DVD a precios increíbles. No me siento particularmente atraído por este formato. Hace mucho tiempo di el salto al formato de alta definición por excelencia [Blu Ray, PlayStation 3 y la terrible estupidez humana por querer ser el primero]. Algo de lo que cada vez estoy más satisfecho. Sin embargo, las ofertas en DVD me recuerdan a mi abuela. Principalmente si, además, son películas clásicas o, vulgarmente conocido, cine en blanco y negro del de antes. Hace unos años le regalé un buen reproductor de DVD y, cuando se presenta la oportunidad, le compro alguna película antigua. De esas que ella disfrutó cuando era joven. No hay nada como el buen cine para alegrar a una vieja (y eso que mi abuela no es especialmente vieja). Y a mí me hace muchísima ilusión regalarle esas películas porque la veo entusiasmada. Es consumismo, lo sé, pero un gesto tan sencillo como gastarse cinco o seis euros alegra a mi abuela con dos horas de buen cine.

Hace menos tiempo tuve una pesadilla. En ella me acercaba a uno de esos cajones. Estaba completamente vacío. En el fondo había un papel manuscrito en el que se leía «creo que el mundo no necesita más DVD ni Blu-Ray» y estaba firmado por Steve Jobs. Lo llamé. Extrañamente en mi sueño tenía el teléfono de Jobs y, más extraño aún, hablaba perfecto castellano —más bien el canarión del cabrón de la clase de tercero de bachiller—. Así que me quejé y le dije que no podía hacer eso. Su respuesta fue sencilla: «ajo y agua». Y se reía con voz de niño perverso. Cuando conseguí que me diese una explicación más coherente me dijo que el futuro eran los implantes capilares de fibra óptica con receptores WIFI de alta definición que me permitirían ver directamente en el cerebro una gama de colores que no me hubiese imaginado. Eso sin contar las sensaciones únicas e inexplicables que viviría con los contenidos directamente descargados de Internet con banda hiperancha tetradimensional a mi cerebro. Eso sí, tendríamos que pagarle a él (por eso de hacer estándares que únicamente funcionan con sus equipos y programas) ya que poseía todas las patentes.

Repentinamente, imaginando todas las implicaciones de aquella estrategia, me sumergí en una insoportable angustia. Entonces desperté agitado.

Ya más tranquilo pensé, entristecido, que de ser cierto que quiere erradicar el formato físico del mundo, ya no podría volver a regalarle una película a mi abuela. Ese pequeño gesto de comprarla, acercarme a su casa y tomarme un té mientras la vemos juntos. ¿Y cómo le prestaría a mis amigos esa película tan fantástica y que atesoro con mucho cariño? ['Home', precioso canto de amor a la Tierra]. ¿O lo de llamar a los amigos y proponer ir a su casa para ver una de las películas que he comprado unos días antes mientras cenamos una pizza? ¿Steve Jobs quería robarme esos pequeños momentos de placer social con los amigos? ¿O lo de acordar con mi padre hacer un pedido conjunto a Amazon UK porque la libra ha caído y allí las películas se venden a precios razonables mientras que en la república de España siguen sacándote los ojos por una película de hace dos años? ¿Quería quitarme también esas pequeñas empresas padre-hijo por el capricho de un tecnófilia extrema al creerse un ser endiosado?


Todas esas preguntas me pasaban por la cabeza tras ese despertar violento y me decía que no era posible que un hombre que había levantado una empresa como Apple, tan encariñada con el usuario final, que nos mimaba tanto, llegase a negarle esos pequeños placeres de compartir y disfrutar con amigos y familiares. ¿No hay que ser muy mala persona para quitarle eso a la gente? Me acosté tranquilo sabiendo que no, que eso no podía ser posible. Mi amigo Steve Jobs no me haría eso.

¿A que es una bonita historia hasta el momento? Pero la realidad nunca es tan humana.

Pues parece que sí, que Steve Jobs pretende quitarnos [Steve Jobs asegura que las descargas derrotarán al Blu-Ray @ Applesfera] esos placeres que, al menos yo, aprecio tanto. No niego que eso no vaya a ocurrir, pero supongo que en países como España, donde el humus técnico aún está muy pobre, a esos arbustos tecnológicos les llevará otros diez años empezar a crecer. Para entonces espero haberle puesto a mi abuela un equipo tipo GoogleTV [@ Google] o un Apple TV [@ Apple] que pueda manejar con la voz, que a cada casa llegue la fibra óptica, que la banda ancha se haya declarado bien necesario e indispensable de primer orden constitucionalmente para que los precios sean asumibles por la recortada pensión de una jubilada, que todo se pueda almacenar en la nube, y que la gestión de contenidos favorezca la creación de grupos familiares que puedan disfrutar del mismo contenido de forma comunal. ¿Es que me van a prohibir prestarle a mi padre una película que yo he comprado?

El modelo que está proponiendo la industria, el mismo que defiende Steva Jobs, y a mi modo de ver, desfavorece la interacción social con los amigos y familiares. Promueve el individualismo y el sedentarismo. En resumen, da otro pasito más en el camino de Los sustitutos [@ FilmAffinity]. No es un modelo que me disguste especialmente, pero tampoco que desee abrazar con fuerza. Al menos no en un futuro cercano. Sin embargo, supongo que será el modelo al que acabará tendiendo todo. Yo me opondré con todas mis fuerzas mientras la industria del Blu-Ray siga siendo una alternativa [La Blu-Ray Disc Association responde a las críticas de Steve Jobs @ Applesfera]. O hasta que cambie de opinión, que ya se sabe que soy muy voluble. Pero hasta que eso ocurra, yo seguiré disfrutando de la mayor calidad posible que me brinden los discos de alta definición que, pese lo que pese al que escribió el último artículo referido y a su fanatismo ciego, son muy difíciles de rayar. Seguiré comprándolos a medias con mi padre, que conjuntamente ya tenemos más de cien películas en este formato. Y seguiré tranquilo sabiendo que mi abuela podrá seguir disfrutando de películas en un modo fácil y cómodo de manipular para una persona mayor.

Para acabar, unas palabras sobre el título de la entrada de hoy. Puede parecer un poco excesivo, lo sé. Se trata de un recurso a las emociones. Forma parte de las falacias informales dentro de los prejuicios cognitivos [@ Wikipedia]. ¿Soy mala persona por ello? ¿Por intentar manipular las emociones de los demás para reforzar mi discurso? Vaya, de verdad que creí que era lícito usarlo cuando hasta las compañías que se mueven principalmente estimuladas por el ánimo de lucro lo hacen. Incluso Apple recurre a ello [Nuevos anuncios del iPhone 4, Apple tocando la fibra sensible @ Applesfera]. ¿A que viendo esos anuncios a uno se le enternece el corazón y le dan ganas de comprar el nuevo iPhone? ¿Y a que no te sientes «manipulado»? Pues espero que con el título de esta entrada a Steve Jobs —y sus cien mil fanáticos— se les ablande el corazón y se apiaden de mi abuela. Para mí su salud es importante.

martes, 13 de julio de 2010

iPhone, MonoTouch y la insoportable levedad del ser: El servidor

Primero fue iPhone, MonoTouch y la insoportable levedad del ser: El Comienzo. Luego vino iPhone, MonoTouch y la insoportable levedad del ser: El Cliente (la prueba). Ahora, en otra espeluznante vuelta de tuerca, le toca el turno al servidor.

Pero antes, abro un pequeño inciso para comentar que ha salido un libro sobre MonoTouch. Mientras escribía el primero de los artículos de esta serie leí (qué grande es el RSS, sí señor) que habían publicado el primer libro -en realidad el segundo- sobre programación con MonoTouch: 'Professional iPhone Programming with MonoTouch and .NET/C#', de la editorial Wrox [@ Amazon]. A día de hoy, lo único que sigo descargando de Internet son libros técnicos. Toda la música y las películas las compro (ya hablaré sobre eso). Pero los libros técnicos los sigo descargando, pues no suelo ni leerlos completos ni mantenerlos mucho tiempo una vez leo lo que me interesa. El resto de libros sí que los compro, so pena de que mi mujer acabe echándome de casa por la cantidad de papel que voy acumulando. Motivo éste, también, para recurrir a lo que la ministra de cultura, en una voltereta mortal al concepto en sí, denomina «piratería», para conseguir los libros técnicos. Del libro en cuestión ya tengo mi copia legal (aunque no muy lícita) en mi disco duro. Sin embargo no he tardado un suspiro en solicitar mi copia impresa (que tardará casi un mes en llegar) por menos de 30 €. Estoy muy entusiasmado con esta tecnología, lo confieso. Lo que me lleva a hacer este tipo de tonterías. Pero mientras llega, seguiré leyendo mi copia legal. Espero que la guardia civil no aporre mi puerta mañana.

Sería bueno que Apple rectificara ya su sección 3.3.1 [Apple podría cambiar la sección 3.3.1 para evitar una investigación antimonopolio @ Appleismo]. No solo porque se evitarían la investigación antimonopolio que también se está planteando en Europa [Apple podría enfrentarse a una investigación antimonopolio en Europa @ Faq-Mac]. Un cambio en la sección 3.3.1 permitiría «estandarizar» .NET como plataforma de desarrollo para iPhone. ¿Y por qué sería bueno? O, mejor preguntado, ¿por qué podría llegar a suceder eso? Pues porque los chicos de Mono están trabajando duramente en una versión para Android: MonoDroid, de la que ya está abierto el programa de trabajo beta [MonoDroid - Mono for Android Beta Program @ Miguel Icaza's Blog]. ¿Alguien me presta un teléfono con Android para probar? Prometo cuidarlo bien, aunque no creo que llegue a devolverlo. Pero no veo la aparición de MonoDroid como una especie de «trabaja una vez y usa en muchas plataformas»; algo que, de todos modos, sería fantástico. Pero más allá de que no se podrá aprovechar el código escrito para el SDK específico de iPhone o de Android, los cuales difieren, sí implica que se podría emplear un mismo lenguaje de programación y, por consiguiente, patrones —e idioms— del lenguaje. O existir bibliotecas de clases para funciones diferentes a las de interfaz de usuario que permitiesen reutilizar código. Se abre un universo de posibilidades.

También estos días he leído un rumor sobre que Apple podría estar preparando un nuevo lenguaje de programación para sustituir Objective-C [Apple podría estar preparando un nuevo lenguaje de programación para reemplazar a Objective-C @ Applesfera] que como todos los rumores se debería coger con pinzas. En cualquier caso yo diría que ese «nuevo lenguaje» ya existe y, perfectamente, podría ser .NET. Sea o no a través de MonoTouch.

En cualquier caso parece que la aparición de este libro permite hacer creer que habrá un sector creciente de gente que tenga ganas de programar para iPhone aprovechando su conocimiento de .NET. Ya veremos. Pero yo me estoy replanteando seriamente adquirir la licencia de desarrollo.

De todas formas, para el puntilloso, comentar que ya existe la posibilidad de desarrollar soluciones multiplataforma: PhoneGap [Homepage]. Sería usando JavaScript y espero tener la oportunidad de probarlo con un poco más de calma y, aún mejor, tener tiempo para escribir sobre ello. Sin embargo, por gustos, yo me decanto más por C# y la cantidad de cosas que ofrece su sintaxis y que, hasta la fecha, no he podido ver en JavaScript (¿dije «tipado fuerte»?).

Fin del inciso. Aunque se podría decir que esto, más que un inciso, es una anotación dentro de una anotación. Qué plasta que soy.

Como decía al principio, hoy le toca la vez a la parte de servidor. En realidad, para ser estricto, la aplicación en sí no necesita la existencia de tal parte. Para las chorradas que podría decir el «adivino», Numerón, se puede perfectamente embeber en la propia aplicación. Pero a efectos del experimento lo consideraba vital. Así que, aunque el servicio en sí sea algo ridículo, vamos a intentar conectar la aplicación cliente con un servicio web hecho a medida.

Tal como hice con la parte cliente, no es mi intención escribir otro tutorial sobre el asunto. Aunque al final acabe adquiriendo cierto tufillo a tutorial. En Internet hay unos cuantos a un click de Google. Por ejemplo, tienes el vídeo Create a web service on Monodevelop C# Linux en YouTube y una serie de documentos PDF en español [Entendiendo Web Services con MonoDevelop]. Entre cientos, si no miles, de documentos y vídeos por el estilo.

En mi caso he creado una Aplicación Web ASP.NET y, luego, he añadido un nuevo archivo de tipo Servicio Web con code behind.



A efectos de la prueba, basta con escribir un código similar al siguiente.

public class NumeronDice : System.Web.Services.WebService
{
  
   public NumeronDice () {}
  
   [WebMethod]
   public RespuestaNumeron Numero ( DatosPersonales datos ) 
   {
   return new RespuestaNumeron ( 42, 
                   string.Format ( "¿Pero de verdad crees en la adivinacion, {0}?", datos.Nombre ) );
   }
  
}

¿Qué ves de «extraño» en el código? Además de usar un tipo de datos, DatosPersonales, como parámetro de entrada y otro, RespuestaNumeron, como resultado. Es uno de esos malos hábitos que he adquirido con los años al «diseñar» servicios web. No, eso no es. Parece una falta de ortografía, pero «adivinacion» sin tilde no es porque yo haya querido dejarlo así. Aún no he conseguido que MonoDevelop me permita escribir tildes. He consultado en el IRC, he leído en el foro y todo apunta a una limitación a la hora de procesar las combinaciones de teclas del port para MacOS de GTK+. O una limitación mía para entender las discusiones en lenguas bárbaras como el inglés. Este ha sido el único contratiempo que le he encontrado al MonoDevelop hasta el momento. Bueno, lo de las tildes y que de vez en cuando le da por colgarse. Generalmente cuando intento escribir la descripción de una región y, por costumbre, o por la letra aprehendida con sangre, intento poner tilde sobre alguna vocal. En esas raras ocasiones se produce un salida imprevista del entorno y toca rezar para que el autoguardado me reponga del susto.

Lo de usar estructuras de datos (clases) como parámetro de entrada y salida es, también, porque deseaba comprobar hasta qué punto funciona la integración de servicios Web SOAP en el código de MonoTouch. A efectos de este pequeño breviario, baste decir que son clases bastante «tontas» sin ninguna funcionalidad más allá de definir propiedades (getters y setters) para que se pueda serializar y deserializar automáticamente a la hora de usarlos en el servicio web.

Si ahora lanzamos la ejecución de la aplicación, podremos acceder a la descripción del servicio en sí (que se asoció al método público con el identificador «Numero»).



Hecho el servicio Web, quedaría incluirlo en el cliente. Aquí me he encontrado con una limitación de MonoDevelop. En realidad es que no he sabido cómo hacerlo, así que busqué una alternativa para salir del paso. Ya seguiré indagando a ver si consigo lanzar dos proyectos a la vez: la aplicación web y el cliente iPhone cuando ambos están bajo la misma solución. Y, hasta donde yo sé, no puedo abrir dos soluciones al mismo tiempo con MonoDevelop. En fin, que para no andar perdiendo mucho tiempo en estas complejidades menores, comentar que existe una forma de salir del paso, como decía. Ya buscaré un mecanismo más elegante de hacer esto mismo. El mecanismo paliativo pasa por lanzar el entorno desde línea de comando. Dos veces. Hala, ¿a que es sencillo? Eso sí, asume que la salida de la aplicación será luego algo abrupta. Tendrás que forzar el cierre del terminal. No siempre, aunque muchas veces el Cmd+Q típico suele dejar colgada la sesión de terminal.



Pudiendo arrancar el servidor —de hecho hay que hacerlo— en una instancia de MonoDevelop y el cliente en otra, podemos crear la referencia al servicio web y depurar cada elemento por separado. Sin embargo, no nos vamos a meter a depurar. Baste ahora con la posibilidad de crear la referencia al servicio web desde el proyecto cliente. Para ello, con la parte servidor en funcionamiento, seguiremos la secuencia de pulsar botón derecho sobre el nombre del proyecto en la vista de solución, «Añadir;» y «Agregar referencia web». En el diálogo rellenar la URL del servicio, el nombre con el se quiere crear y, esto sí es importante de momento, indicar que se trata de un servicio web .NET 2.0 en lugar de uno de la más moderna arquitectura WCF [@ Wikipedia | @ MSDN Microsoft] que, sin embargo, es el que ofrece por defecto. Hay un How-To que enseña los pasos a dar para hacer uso de la variante WCF [Using WCF @ MonoTouch Wiki].



La invocación del método desde el código cliente, una vez se ha creado la referencia al servicio web, podría tener la siguiente forma:

private SWNumeronDice.RespuestaNumeron CalcularNumero ()
{
   SWNumeronDice.DatosPersonales datos = new SWNumeronDice.DatosPersonales ();
   datos.Nombre = this.nombreTextEdit.Text.Trim ();
   datos.Apellidos = this.apellidosTextEdit.Text.Trim ();
   datos.FechaNacimiento = _diaNacimiento.Value;
   datos.FechaPrediccion = _diaFuturo.Value;
   datos.Sexo = (this.sexoSegmentedControl.SelectedSegment == 0) ? SWNumeronDice.DatosPersonalesSexo.Hombre 
         : SWNumeronDice.DatosPersonalesSexo.Mujer;
    
   return new SWNumeronDice.NumeronDice ().Numero ( datos );
}

La inclusión de un servicio web dentro del cliente para iPhone usando MonoTouch mantiene el mismo esquema que teníamos para los clientes de escritorio, donde se crean versiones con tipado de las estructuras que se pasan como parámetros y/o se obtienen como respuestas. Esto permite tener el código funcionando en cuestión de minutos mientras nos aseguramos que en tiempo de compilación se detectarán problemas de tipo de datos.

Con la respuesta, se podría hacer algo como:

public override void ViewDidLoad ()
{
   Title = "Numeron dice...";
   numeroLabel.Text = this.respuesta.Numero.ToString ();
   cuentoLabel.Text = this.respuesta.Cuento;
   
   base.ViewDidLoad ();
}

El resultado de la ejecución sería algo como:



Con esta última ejecución del cliente, ya podríamos dar por cerrado el experimento. A partir de este punto quedaría enriquecer tanto la parte cliente como la parte servidora con todo aquello que se considere oportuno incorporar. Por mi parte dejaré para dentro de unos días unos pequeños comentarios sobre la experiencia en sí. Intentaré que sea más estructurada y funcional. Y breve. Sin embargo, concluyo la entrada de hoy con la esperanza de que esta pequeña prueba haya servido para demostrar cuán fácil es hacer un proyecto con un lenguaje moderno como .NET y que, con ello, sirva para atraer nuevos adeptos a la causa de MonoTouch y por la abolición de la sección 3.3.1 de la licencia de desarrollador de Apple para iPhone.

domingo, 11 de julio de 2010

Calima, viento, cámaras y windsurfistas

Este viernes, al salir del trabajo, me recogió Luis, en su coche que no es todo terreno pero que el propietario está empecinado en meterlo en cualquier sitio, como ya conté hace unos días en Paseo con Luis, Sulaco y un holandés (supuestamente no errante), y cogimos carretera directos a Pozo Izquierdo para ver la final —¿o se disputaría el sábado? No presto mucha atención a este tipo de cosas— del campeonato de windsurf de este año. Sí, ya, ya, que sé que ha pasado todo un año desde la primera vez [Mi primera vez fotografiando windsurfistas en Pozo Izquierdo]; y que el año ha pasado volando. Que ya sueno cansino con eso de que el tiempo pasa volando también lo sé. Eso sí, aún con las prisas para llegar a tiempo de fotografiar algo, paramos a recoger a Marcos que también se apunta a un bombardeo. Siempre y cuando el bombardeo implique usar la cámara. Su nueva cámara. Resulta que todavía hay gente que apuesta por las Pentax.

La calima nos jodió las instantáneas. Al menos a mí. Al estilo de la otra vez, que también había una calima incómoda. Fastidia llegar a casa y ver que todas tus fotos tienen un tono marrón o amarillento. Pero eso no fue lo peor. También aportó algo mi manía de no hacer caso a los «expertos» Llevé la cámara tal cual, como el año pasado, sin una protección en condiciones. Al minuto tenía la lente —filtro mediante, eso sí— completamente llena de microgotas de agua y salitre. Y a tomar por culo todas las fotos a partir de ahí. Mira que Luis me lo avisó. Tras revisar durante un rato las fotografías que hice he decidido dejarlo para otro momento, porque ya me estaba poniendo como una moto por tanta frustración. La que produce ser tan inútil. A ver si la próxima vez que las revise encuentro alguna interesante. Y a ver si la próxima vez que vayamos tenemos mejor suerte con la climatología y, de paso, hago caso a los buenos consejos que me den para intentar evitar tener la lente completamente empañada/sucia al minuto de haberle quitado la tapa protectora.

Aunque, si los rumores son ciertos, me parece que el año que viene no habrá campeonato.

Windsurfista por los aires

No sé si es cosa mía, que ya comentaba hace unos días que lo de la fotografía no me tiraba tanto como antes, y puede que con ese color de cristal revise la situación, pero la cosa la encontré bastante desanimada. Cierto que llegamos en el último minuto, cuando competía el último participante. Sin embargo ya iba condicionado a que todo el mundo comentara que este año la cosa andaba bastante floja en todos los aspectos. Menos días, menos participantes, menos dinero para acomodar a los participantes… y para el evento en sí. Menos de todo. En fin, que parece que no soy yo el único que anda desganado. El dinero no quiere ser empleado en pagar un campeonato que lleva una jartá de años celebrándose. ¿El principio del fin? ¿Lo celebrarán el año que viene?

El año pasado me acomplejé. Pero este año, así tiene algo bueno el traerme un poco sin cuidado el arte de la instantánea, ver a gente con unos «lanzamisiles» de objetivos me daba igual. Creo que llegué a ver un 600 milímetros de Canon, si no era más grande aún. Y ese objetivo cuesta unos ocho mil euros. Ni en los sueños más verracos y húmedos, durante mi época más aficionada a la cámara, llegué a soñar con un objetivo así. Vamos, que tan inimaginable me resultaba llegar a tener un bicho de ese calibre, que simplemente no cabía en ninguna de mis fantasías más enfermizas. Forzarme —pero con un esfuerzo extremo— a imaginar colocar un objetivo de esas características en mi cámara podría llevar a un colapso el universo conocido.

Lo obvio en estos casos es hablar de cámaras. Luis y yo tenemos cámaras que ya llevan unos cinco años en el mercado. Esto de las cámaras digitales es como los ordenadores a principios de los noventas, cuando yo viví el (o parte del) boom de los PC's. Mi primer PC, un 386 con 4 Mb de memoria RAM, me costó cuatrocientas quince mil pesetas (al cambio unos dos mil quinientos euros de ahora) que estuve pagando durante cuatro años. Y el PC estaba obsoleto a los dos. Fue cuando la competición entre los paquetes ofimáticos conseguían que tu ordenador no sirviese ni para escribir tres líneas pasados unos pocos meses. De los juegos ya ni hablo. Los procesadores de las cámaras, los sensores y el tratamiento que se hace en la captura, consiguen que las cámaras digitales se queden obsoletas. O que uno sienta que se ha quedado obsoleta. No estaría de más que de una vez por todas sacaran una cámara «actualizable». Sentir que tu equipo ya está viejo es el efecto secundario indeseable que produce leer prensa «fanática». ¿O se dice especializada? Tanta novedad y tanto avance han conseguido que me da vergüenza enseñar mis fotos tomadas a 400 ISO. El ruido es tan asqueroso que me siento como me sentía en mis pesadillas infantiles más horrendas, dentro de las cuales me presentaba en el colegio cinco minutos tarde y extenuado de tanto correr para descubrir que iba con calzoncillos nada más. Lo curioso es que eso antes, recién comprada mi querida D200 [Mi experiencia con la Nikon D200], me daba bastante igual. El grano es artístico, decía. Ahora también me importa poco, cuando a veces me planteo vender el equipo. Pero sé que en cualquier momento volverá a picarme el dedo y querré salir a capturar imágenes como hacía antes. Soy consciente que esto es por épocas.

Creyendo en que llegará una de esas épocas a veces me planteo cuál sería el cambio. De eso estuvimos hablando, refresco en la mano, rodeados de windsurfistas que celebraban la victoria del día. Ellos ajenos a nosotros y nosotros esperando que se animaran a seguir practicando para tirar las últimas fotos antes de darnos por satisfechos. A diferencia de Luis, por ejemplo, a mí no me importa cargar con diez kilos en equipo fotográfico. Egipto fue un caso extremo, eso es cierto. Estaba casi estrenando D50 y estrenando D200, que compré el día anterior a volar para allí. Dos cámaras y varios objetivos muy cutres. Pero me divertí mucho pese al peso. Desde entonces, en el resto de viajes, suelo llevar un cuerpo nada más y dos o tres objetivos. Lo «justo». Aún así no menos de cuatro o cinco kilos. Por eso no creo que vuelva a una compacta con un ultrazoom, como la Coolpix 5700 que tuve antes de la primera reflex digital. Cierto que a veces lo pienso. En realidad, lo que me planteo es si pasaré al full frame o si me quedaré en APS-C. Lo bueno del formato APS-C es que para los teleobjetivos supone un incremento de la focal sin perder —eso dicen— calidad en la óptica. Lo mejor del formato completo es que tiene mayor calidad a igual megapíxeles y es más versátil para los angulares. Yo estoy más por cambiar al formato completo. Una D700, o lo que sea entonces, sería la opción deseable. Aunque tengo claro que eso no será, si es que llega a ocurrir, hasta el próximo año, como muy pronto. Creo que aguantaré con mi D200 hasta finales de 2012. No vaya a ser que los mayas estuvieran en lo cierto y me vaya al infierno con plazos pendientes de la nueva cámara. El cura de mi parroquia asusta a los niños diciéndoles que Lucifer tiene acciones en tu banco y que a los morosos los trata especialmente mal. Pero si opto por soltarme el pelo —sí, sí, el que mi calva echa ya de menos— el año que viene, para entonces hará ya cuatro años que tengo la Nikon D200. Como hice con mi primer PC, cuatro años puede ser el tiempo justo de amortización antes de sustituirla por otra mejor.

Hay gente que dice que la fotografía es una afición cara. Yo creo que no es tan cara. Aunque es mejor decir: no más cara que otras aficiones. Está claro que no todo el mundo se puede permitir adquirir un equipo fotográfico de gama alta. Igual que no todo el mundo se puede permitir un coche de veinticuatro mil euros. O un viaje de tres semanas a Nueva Zelanda. O, ya puestos, un iMac de veintisiete pulgadas. Y eso que veo a muchos con esos coches. O viajando cada año a las antípodas. O pillándose un pedazo de equipo informático que quita el hipo.

Tampoco es necesario que todo el mundo se compre una cámara cara, claro, volviendo a la fotografía. Para muchos existen alternativas más económicas que ofrecen resultados espectaculares. Pero hagamos unos sencillos números. Mi cámara D200 me costó mil quinientos euros. Me durará al menos cuatro años. Repartido de forma mensual, esos mil quinientos euros suponen unos treinta euros mensuales (mil quinientos entre cuarenta y ocho meses). Por tener ADSL en casa, lo que me obliga a una línea fija, pago unos cincuenta euros al mes. Por establecer un valor de comparación. Pero aún más. Suponiendo que llegue a dar el salto a una full frame la cámara se quedará como segundo cuerpo y no perder la posibilidad de multiplicar las focales tele. Para cuando se caiga a cachos, o se convierta en un pisapapeles bonito, la amortización mensual será aún menor.

Pero volvamos a esos treinta euros al mes que se queda de amortización de esos cuatro años de uso y disfrute. Ahora haz cuentas de la última vez que saliste a cenar con unos amigos a tapear. ¿A cuánto tocó por cabeza? ¿A veinte o veinticinco? ¿Y las copas que luego te tomaste en una terraza para alargar un poco más la velada y terminar de ponerte al día? Una noche así puedo gastarme entre treinta y cuarenta euros. Como poco. Pero voy con mi mujer, así que nos gastamos el doble recurriendo al mismo fondo de tesorería. ¿Cuántas veces se sale al mes a cenar con los amigos? Dado que no soy un tipo muy activo socialmente, no muchas. Por suerte para mi tesorería, pero para desgracia de la inmortalidad de mi memoria.

Y hay muchas otras comparaciones similares. De hecho, hay pocas aficiones, se me ocurre ahora, que sean «económicas» cuando te introduces a fondo en ellas. No soy nada aficionado al windsurf, pero en Internet puedes buscar precios de equipamiento. El equipamiento básico —de iniciación, vamos— de tabla, vela, mástil, neopreno, etcétera, etcétera, puede costar unos mil quinientos euros. De iniciación, repito. Un mástil de carbono superligero te puede costar él solito quinientos euros. Y una tabla mínimamente digna unos mil doscientos. ¿Y a los aficionados al ciclismo? Una bicicleta ultraligera te puede costar dos mil quinientos euros o más. ¿Y un sistema de reproducción de audio de alta definición de calidad infinita? Sé de uno que se gastó más de millón y medio de las antiguas pesetas en un sistema de reproducción de audio perfecto. ¿Y el que se gastó los seis o siete mil euros que costaban los primeros televisores de plasma? ¿O los tres mil que está costando ahora uno de los nuevos LED 3D? ¿Quién está dispuesto a gastarse esa pasta en una tele que va a poner en su salón? Lo triste es que muchos lo hacen y luego se descargan los screeners con la mula. Pero eso es otra historia.

Sé que todo esto no deja de ser una justificación sobre mi proceso de autofijación de precios, pero he querido insistir en remarcar que, en el fondo, no vemos como «caro» lo que estamos dispuestos a comprar nosotros y sí mucho lo que otros están dispuestos a gastarse en las aficiones que tienen. Seguramente si le hubiese dicho a alguno de los chicos que competían allí que mi cámara había costado mil quinientos euros se hubiese llevado las manos a la cabeza al tiempo que le parece de lo más normal pagar mil novecientos por una tabla Formula 162 de 2009 [@ Triboo Wind]. Lo mismo que a mí me entraron escalofríos cuando un compañero me dijo que se iba a comprar un todo terreno «de ciudad» que le costaría cincuenta mil euros. Creo que se me saltaron los ojos de las órbitas cuando me lo dijo.

Cada loco con su tema, como decía aquel.

De todas formas lo realmente caro no es la cámara. Una full frame «exige» unos objetivos mejores. Aunque Marcos diga que lo importante sean los megapíxeles y no las lentes. Igual que el tema de los precios, a mí sí me parecen importantes. Por eso no se me ocurriría dar el salto al formato completo sin renovar los objetivos. Y eso es una pasta. Aunque, al igual que justificaba con el cálculo mensual de amortización la adquisición de la cámara, los objetivos tienen un tiempo de vida mucho mayor. ¿A cuánto se quedarían el cálculo mensual los dos mil euros de una lente que dure diez o quince años? A mí me salen unos dieciséis o veinte euros.

sábado, 10 de julio de 2010

iPhone, MonoTouch y la insoportable levedad del ser: El cliente (la prueba).

Ya decía ayer [iPhone, MonoTouch y la insoportable levedad del ser: El comienzo] que quería dejar constancia escrita (a modo de recordatorio para el futuro dentro de la saga Cuadernos del tolete [@ mi blog], también) de lo que observé al probar MonoTouch [Web oficial]. Y compararlo, en la medida de mis limitaciones, con las otras alternativas que he ido revisando: PhoneGap [Web oficial] y el propio Objective-C [@ Apple].

Lo primero que hay que saber es que desarrollar para iPhone exige trabajar sobre un Mac. Pese a que Mono [Web oficial] es multiplataforma, MonoTouch no. Bueno, sí pero no. Se puede desarrollar con Windows, creo, pero no sé cómo se resolvería la parte del simulador y, lo que es más importante, la gestión de los perfiles para «subir» el código a un terminal. Tampoco me he preocupado mucho en ese aspecto. Así que, si las cosas no han cambiado, se requiere igualmente usar un Mac para desarrollar con MonoTouch.

XCode 3 [@ Apple] no es santo de mi devoción. Así que he preferido usar MonoDevelop [Web oficial], ya que es «la herramienta definitiva» para el desarrollo .NET sobre Mac. Será también la que use para hacer un pequeño servicio Web correspondiente a la parte de servidor. Sin embargo, MonoTouch trabaja con la herramienta de diseño de interfaces de XCode, Interface Builder, y requiere el simulador de iPhone/iPad para poder ver el resultado. Por todo ello, se requiere instalar XCode con el SDK de iPhone.

Resumiendo, los pasos que vamos a necesitar dar para empezar serán:
  1. Tener un Mac. Si no es tu caso, hasta aquí «podemos leer».
  2. Descargar e instalar XCode + SDK de iPhone, para lo que debes estar dado de alta como desarrollador (gratis) en el iPhone Dev Center [Web principal].
  3. Descargar e instalar Mono para Mac [Download @ Mono Project].
  4. Descargar e instalar MonoDevelop para Mac [Download @ MonoDevelop].
  5. Descargar [Download Trial @ MonoTouch] e instalar [Installation @ MonoTouch] MonoTouch.

Cabe la opción de instalar Mono y MonoDevelop usando MacPorts [Homepage]. Yo lo hice [MacPorts y Postgresql 8.3]. Y me dio tantos problemas que tuve que eliminarlo todo y volver a instalar MacPorts. Desde entonces igual ya han resuelto los problemillas que tuve. Pero la instalación desde los paquetes oficiales es mucho más cómoda. Y, al menos en mi caso, no tengo intención de deinstalarlos en un futuro próximo. Se quedan.

Tan solo en el primer punto ya te vas a pegar un buen rato. XCode se distribuye con dos «sabores» (al menos): con y sin SDK de iPhone. Si, como fue mi caso, que ya tenía la variante «sin», cuando quieras «añadir» el SDK de iPhone vas a tener que descargar igualmente todo. Unos dos gigabytes y pico. Como dije, vas a tener para rato. Salvo que vivas en un país desarrollado y tengas una buena comunicación ADSL (o similar) a precios asumibles y competitivos. Yo sigo pagando treinta euros por una conexión que a duras penas llega a 1 Mb porque las operadoras pasan de actualizar el cableado de la zona. Para mí, descargar el SDK es cosa de horas.

MonoTouch es un producto de pago. Pero para desarrollar y probar sobre el simulador no tienes que gastarte ni un euro. Sin embargo, tendrás que registrarte igualmente para que puedas usar la versión trial.

Hubiera sido mucho más fácil —y también mucho menos divertido— hacer capturas y contar lo que hice para la prueba de concepto de la empresa —que, por cierto, el cliente al final decidió posponer el proyecto hasta un momento mejor; de la noche a la mañana la presión de tiempo desapareció—, pero la cláusula de privacidad —y la lealtad, principalmente— me impiden «abusar» de la confianza depositada sobre mí en ese aspecto. Así que he decidido, para esta serie de artículos, fabricar una aplicación tonta que me permita, eso sí, probar varias cosas. ¿Podría hacer algo, además, «comercialmente» interesante para un posible mercado objetivo?

Después de darle varias vueltas se me ocurrió que no hay nada más «universal» que la superstición (y su prima bastarda la charlatanería). Vaya, donde vaya, siempre encontrarás alguien dispuesto a creer que el zodiaco define el carácter de las personas: «¡Ah! ¡Que eres Tauro! Eso lo explica todo…». Pero seamos francos: ¿A cuánta gente conoces que no lea el horóscopo cuando cae en sus manos un periódico? No he preguntado «creer». He dicho «leer».

Rebusqué qué artes malignas arcanas se usan para la adivinación o establecimiento de tus dotes metafísicas y sobrenaturales y tropecé con la Numerología [@ Wikipedia]. Fácil de entender y fácil de calcular. Igual carencia de base científica. Perfecto para mis fines.

Sagan [@ Wikipedia | The Carl Sagan Portal] estará revolviéndose en su tumba. De verdad que lo hago con intenciones pedagógicas, nada más. De momento mi ánimo de lucro anda ridículamente desaparecido.

Al esperpento lo he llamado «Numerón dice». Y a continuación contaré algunas de las vicisitudes, y alegrías, que me ha dado programarlo usando MonoTouch. No voy a explicar las interioridades y particularidades del SDK de iPhone ni de Objective-C. En todo caso algún detalle concreto. Hay muy buenos tutoriales al respecto. Por ejemplo los que puedes encontrar en la sección al respecto en la Web de MonoTouch [Tutorials @ MonoTouch]. Sí es importantísimo, en cualquier caso, tener muy claro que todo el SDK de iPhone (la parte gráfica de CocoaTouch, al menos) se diseñó para respetar el patrón Modelo-Vista-Controlador [@ Wikipedia]. Hay que tenerlo presente porque toda «pantalla» que se vaya a diseñar —incluso cuando diseñemos conjuntos de controles complejos que pretendamos reutilizar— exigirá la creación de una clase controladora que será la responsable de decirle a la vista qué elementos ha de presentar y cuáles no. Pero lo dicho, no es este el lugar para dar una charla extensa al respecto. Hay multitud de tutoriales en Internet que explican eso mucho mejor de lo que yo podría hacerlo.

Hay que señalar que todos (o la mayoría) de esos tutoriales (y de los que encontraremos en Internet) se fundamentan en el uso de Interface Builder, que a su vez tiene su propio «lenguaje», con sus «outlets», sus «actions» y cómo se «enganchan» visualmente. Particularmente prefiero «hundirme en el fango» y programar «a pelo» si lo que busco es interiorizar las particularidades del SDK, pero a efectos prácticos, hacerlo con Interface Builder resulta más rápido y cómodo, pese a sus particularidades frente a otras herramientas de diseño de interfaces de usuario. Al principio cuesta un poco hacerse con las ideas inherentes a la construcción de interfaces de usuario usándolo, pero son tres o cuatro ideas básicas que rápidamente se pillan. Una vez aprehendidos los conceptos, las interfaces de usuario se sacan como churros. Lo «bueno» de usar Interface Builder es que será independiente del lenguaje. Te servirá tanto para Objective-C como para MonoTouch. Los conceptos son exactamente los mismos.

Pero empecemos. Si has trabajado con cualquier IDE (Eclipse, NetBeans, XCode, Visual Studio, etc.) sabrás que todos presentan una serie de principios comunes. Entre ellos está el que, cuando solicitas crear un nuevo proyecto, sobre todo cuando te permiten programar/hacer múltiples tipos de proyectos o usar varios lenguajes (hoy en día todos te lo permiten), te aparece una guía donde te deja elegir el tipo, lenguaje y dónde vas a almacenarlo. Para un proyecto iPhone usando MonoTouch —en nuestro caso pasaremos del iPad—, elegiremos el basado en el componente UINavigationController [@ Apple Developer], tal como muestra la siguiente captura. O sea C# --> iPhone and iPad --> iPhone Navigation-based Project.



Nada más pulsar sobre el botón de «Aceptar» para crear el proyecto, ya tienes un código ejecutable basado en una elemento UITableView [@ Apple Developer] y un UIViewController [@ Apple Developer] que implementa el protocolo UITableViewDataSource [@ Apple Developer], y que si se ejecuta (sobre el simulador), nos muestra la tabla con varias filas vacías. Las siguientes capturas presentan el árbol de proyecto recién creado y la primera ejecución inmediata.



Para el que no haya tenido aún un encuentro con Objective-C, sirva aclarar que el concepto equivalente más cercano de un «protocolo» de Objective-C en Java o .NET es el de «interface». La definición de un «contrato» que debe cumplir aquel que lo implemente. Existe, sin embargo, una salvedad y por ello resulta tan atractivo y fundamental en los frameworks de Objective-C. Permite que la implementación de parte de los métodos sea opcional. Resumiento, cuando en C# o en Java dices que una clase se acoge a una interfaz determinada, el compilador te obliga a implementar cada uno de los métodos definidos en el contrato de la interfaz. En Objective-C, únicamente te «obliga» a implementar aquellos métodos que el protocolo no haya definido como opcionales. Hasta la fecha, de los protocolos que he utilizado en mis pruebas, la gran mayoría es básicamente opcional. Por ejemplo, si revisamos la documentación del protocolo UITableViewDataSource comentado antes, de los once métodos que se definen, únicamente dos son obligatorios o requeridos. Esto ahorra escribir mucho código vacío. Si vas a trabajar con Objective-C.

En .NET, en particular en C#, la posibilidad de «tan sólo» implementar los métodos que se necesitan se consigue usando los delegados [@ MSDN Microsoft]. Y buena parte de la capa de adaptación implementada por MonoTouch para enganchar con el SDK de iPhone ha hecho esto mismo. Por ejemplo, el componente UIActionSheet [@ Apple Developer] requiere que se le indique un «delegado», el protocolo UIActionSheetDelegate [@ Apple Developer], que será el encargado de procesar la pulsación del botón que se elija. Generalmente esto implica que el controlador que lanza el action sheet en respuesta a algún evento del usuario, deberá pasarse a sí mismo (self, en Objective-C) como delegado y, por tanto, implementar (muchas veces «también») el protocolo UIActionSheetDelegate. Con MonoTouch podemos enganchar un método a una propiedad de tipo delegado definida en la clase UIActionSheet y de nombre «Clicked». El código resultante podría tener un aspecto como el siguiente:

_actionSheet.Clicked += (o,e) ==> { 
      if (e.ButtonIndex == 0) 
      { 
         ... 
      } 
   };


También se puede implementar un protocolo (que en MonoTouch te obliga a implementarlo todo, no hay nada opcional, porque en realidad se ha resuelto como una clase) o usar un delegado débil. Una explicación más detallada sobre cómo «enganchar» con el SDK lo puede encontrar en la explicación que dan del diseño del API en MonoTouch [API Design @ MonoTouch].

Dependiendo de las necesidades se tendrá que resolver conforme a alguna de las formas disponibles, pero resulta mucho más rápido, a mi modo de entender, hacer uso de los delegados. Siempre y cuando, claro, no tengas que devolver un valor. Los delegados únicamente sirven —en el contexto de MonoTouch— para métodos void.

Dentro de las cosas negativas encontradas, fue precisamente con UIActionSheet con lo que tuve un tropiezo que me hizo perder cosa de cinco o seis horas. Parece que no puedes lanzar un UIActionSheet dentro del método de respuesta a un evento haciendo uso (definiéndolo) como una variable local del método y enganchándole un delegado ad-hoc como el del código anterior. Revienta por todas partes. Fue un verdadero quebradero de cabeza hasta que encontré una discusión al respecto en los foros de MonoTouch [Trouble with Action Sheets @ MonoTouch Forums]. La solución pasa por definirlo como instancia de clase y crearlo durante la inicialización de la misma. Se deja inactivo hasta que se necesite mostrar. Esto me hizo restarle muchos puntos a MonoTouch.

Sigamos, que acabábamos de empezar y habíamos credo el proyecto y ejecutado el código por defecto.

Si pulsamos dos veces sobre los archivos que terminan en .xib se abrirá automáticamente el Interface Builder, lo que nos permitirá toquetear y diseñar la interfaz de usuario. La siguiente captura presenta el aspecto de los dos controladores que se crean automáticamente: MainWindow y RootViewController.



El primero —MainWindow— será el básico, el principal, el que hará de continente del resto. MainWindow es el controlador base, que hereda de/implementa el protocolo UIApplicationDelegate [@ Apple Developer]. En la captura se puede observar que ya «trae» un elemento visual que es el UINavigationItem [@ Apple Developer] que será gestionado por el NavigationController correspondiente.

Mientras tanto RootViewController, que por defecto es un controlador de una tabla, es el que primero se añade a la subvista definida en MainView. Yo me cargué directamente RootViewController y cree uno nuevo. Podía haberlo llamado como el que acababa de extinguir, pero lo abrevié. Cosas del directo.

Para crear un nuevo archivo .xib con el controlador, basta seguir las opciones Archivo --> Nuevo --> Archivo… y elegir



Esto nos creará un nuevo archivo .xib que podremos abrir con Interface Builder y nos mostrará una vista en blanco. A partir de ahí se podrá rellenar con lo que se quiera. En mi caso, este es el aspecto elegido:



Austero.

Aquí viene la parte de «enganche» entre la estructura generada por Interface Builder (el .xib) y el código C#. U Objective-C, pues el principio es exactamente el mismo. Interface Builder encapsula todo lo que pintemos en la vista o creemos directamente con él. Desde el exterior no se puede acceder a nada. Es una «caja negra» a todos los efectos. Salvo que le señalemos los «puntos de enganche». En el argot de Interface Builder esto se puede hacer usando «outlets» y «actions». Un «outlet» expone un componente visual al completo. Por ejemplo un UILabel [@ Apple Developer] o un UIButton [@ Apple Developer]. Lo que permite acceder a todas sus propiedades y métodos. Por su parte, un «action» facilita abstraer qué elemento lanza la acción.

No basta con definirlos, también hay que asociarlos visualmente. Pero eso ya lo dejo para que se busque en el tutorial que corresponda. En mi caso opté por outlets y «publiqué» los elementos de interacción de la interfaz. En mi caso, además, preferí darle un «tipado fuerte» desde el propio Interface Builder indicando la clase que debe admitir ese outlet. Objective-C ofrece un tipo débil genérico, «id», que se emplea para pasar elementos que pueden ser de distinto tipo. Es la base, por ejemplo, para gestionar las colecciones (arrays, diccionarios, etc).



Esto me permitió asociar delegados a los botones, por ejemplo, en el evento ViewDidLoad. Dicho evento se ejecuta justo cuando se concluye la deserialización de un archivo .xib, en tiempo de ejecución, y se desea finalizar la inicialización de los elementos que lo componen. Tal como muestra el siguiente código:

public override void ViewDidLoad ()
{
   base.ViewDidLoad ();
  
   this.nombreTextEdit.EditingDidEndOnExit += this.DidEndOnExit;
   this.apellidosTextEdit.EditingDidEndOnExit += this.DidEndOnExit;
   this.nacimientoButton.TouchDown += this.TouchButtonNaciste;
   this.sexoSegmentedControl.ValueChanged += this.SexoChanged;
   this.diaFuturoButton.TouchDown += this.TouchButtonDiaFuturo;
   this.miFuturoButton.TouchDown += this.MiFuturoAUnClick;
}

La introducción de las fechas las monté usando Action Sheets, que se lanzan cuando se pulsa sobre el botón que tienen los textos solicitando las fechas. La siguiente captura muestra la aplicación en ejecución y lo que se muestra al pulsar el botón «Dime en qué fecha naciste».



Colocar un UIDatePicker [@ Apple Developer] dentro de un UIActionSheet tiene algo de miga. El truco lo dejo para que lo busquen en Internet.

Otra de las cosas que me quitó mucho tiempo fue «esconder» el teclado cuando terminaba de introducir el nombre y el apellido. Por más que miré y remiré no encontré una propiedad del componente UITextField [@ Apple Developer] que me facilitara el saltar al siguiente control o a esconderlo tan pronto terminase de escribir. Al final tuve que recurrir a una artimaña por código. Y por lo que he visto, esto es así también en Objective-C. La «culpa», en este caso, no es de MonoTouch. La «solución» pasa por crear un delegado y añadirlo al evento de UITextField, EditingDidEndOnExit, tal como se muestra a continuación.

this.nombreTextEdit.EditingDidEndOnExit += this.DidEndOnExit;

Este delegado no existe como tal en la clase UITextField del SDK de iPhone. A la hora de diseñar el API de MonoTouch, y su enlace cono el SDK de iPhone, se optó por añadir algunos «extras», como que la clase UITextField tenga ese evento. En Objective-C se tendría que resolver implementando el protocolo UITextFieldDelegate [@ Apple Developer] y decirle al text field en cuestión cuál es el delegado responsable de responder a ese método. Varios puntos positivos para MonoTouch por esta iniciativa.

En el código del delegado debemos retirar el foco (first responder) del elemento para que se oculte automáticamente el teclado invocando el método ResignFirstResponder.

void DidEndOnExit (object sender, System.EventArgs args) 
   {
      UITextField tf = (sender as UITextField);
      if ( null != tf ) {
         this.ResignFirstResponder();
      }
   }

Una de las cosas que me encanta de usar C#, tanto para el desarrollo en general como para desarrollar para iPhone en particular, es la posibilidad de usar la estructura genérica Nullable [@ MSDN Microsoft] y simplificar las preguntas cuando se tratan de tipos o estructuras que no admiten estados nulos, como int o DateTime (la estructura de C# para las fechas). De esta forma, las condiciones se simplifican. El código que lanza la visualización del resultado podría estar condicionada a introducir todos los datos y tener un aspecto como el siguiente:

void MiFuturoAUnClick (object sender, EventArgs args )
{
   // Comprobamos que estan todos los datos
   string nombre = this.nombreTextEdit.Text.Trim ();
   string apellidos = this.apellidosTextEdit.Text.Trim ();
   Nullable<int> sexo = this.sexoSegmentedControl.SelectedSegment;
   Nullable<DateTime> diaNacimiento = null;
   Nullable<DateTime> diaFuturo = null;

   nombre = ( nombre == string.Empty ) ? null : nombre;
   apellidos = ( apellidos == string.Empty ) ? null : apellidos;
   diaNacimiento = fechaElegidaNacimiento ();
   diaFuturo = fechaElegidaFuturo ();

   if ( ( nombre == null ) || ( apellidos == null ) || ( _diaNacimiento == null )
            || ( _diaFuturo == null ) || ( sexo == null ) ) 
   {
      new UIAlertView ( "¡Faltan datos!", "Faltan datos para poder hacer un buen calculo de tu proximo futuro", 
               null, null, "Pues muy bien" )
         .Show();
   }
   else
   {
      this.NavigationController.PushViewController ( new NumeronDice( CalcularNumero () ), true );
   }
}

En el anterior código se puede observar que, en caso de tener alguna de las entradas de datos a null, se lanzará una alerta con un mensaje indicando que no está todo. Para eso se emplea UIAlertView [@ Apple Developer]. Este componente del SDK es similar a los Action Sheet y en este caso no se ha asignado ni delegado (protocolo Objective-C) ni delegado (evento C#) para responder a los eventos de pulsación sobre los botones. Únicamente se usa para informar que no tenemos todos los datos y solo presenta un botón para salir del mensaje.



La otra cosa interesante a reseñar, dentro del código anterior, es el método PushViewController de la clase UINavigationController. Cuando empleamos un esquema de navegación usando UINavigationController, el SDK de iPhone ya gestiona muchas de las cosas comunes, como mostrar un botón de vuelta atrás con el nombre de la «pantalla» que acabamos de dejar. Para ello lo gestiona usando una pila de controladores. Cuando queremos que aparezca una nueva «pantalla» sobre la anterior, pero que se ofrezca la posibilidad de volver (sin intervención de código) a la anterior, se apilará (push) sobre la que esté activa en ese momento.

A continuación un adelanto, a modo de captura, de cómo podría ser la vista con los resultados.




Pero su acabado definitivo lo dejaré para la siguiente entrega de esta fascinante serie. Será cuando se integre con el servicio web creado para conocer el futuro de todo aquel que esté interesado. No te pierdas, por tanto, el próximo capítulo. Pronto, pronto.

De momento decir que, si Apple entra en razón, MonoTouch es una herramienta con un valor incalculable para agilizar el desarrollo de aplicaciones para iPhone, iPad e iPod Touch. Únicamente quedaría saber qué tal se desenvuelve el rendimiento en estos terminales. Algo que, me temo, no llegaré a saber a ciencia cierta hasta que decida comprar la licencia.

viernes, 9 de julio de 2010

iPhone, MonoTouch y la insoportable levedad del ser: El comienzo

Cumplido ya el primer semestre del año 2010 puedo asegurar que el año se está desarrollando de forma excesivamente extraña para mi gusto. Bastante revuelto. Y no necesariamente tiene que ver con la crisis económica que está poniendo patas arriba todo y a todos. Un año raro. Muy raro.

Raro en el aspecto laboral también. Y esto tal vez sí se excuse en la crisis. Tal vez. Me encuentro en un constante «ahora sí, ahora no» y los proyectos que empiezo se caen con «mucha facilidad». Hoy te dicen que sí, trabajas todo un fin de semana para adelantar y el lunes a primera hora te dicen que se lo han pensado mejor y que va a ser que no. Espero que el segundo semestre sea más tranquilo y el balance anual mejore.

Una de las cosas que hice en los últimos meses de mi estancia en Madrid estuvo relacionado con un proyecto para iPhone. Por simplificar diré que las personas que tenían experiencia en desarrollo para iPhone estaban involucrados en otros proyectos que no podían abandonar de ninguna manera. Simplemente imposible e impensable. Así que, de la noche a la mañana, tres pelagatos nos vimos involucrados en un proyecto para el que, técnica y cognitivamente hablando, teníamos bastantes lagunas. Aunque no negaré que me encantaba la idea de participar en un proyecto para iPhone, algo que llevaba tiempo deseando.

No me asusta el desconocimiento en tecnología ni en lenguajes de programación. Es lo que me gusta, tengo suficiente bagaje para aprender con rapidez y mis decisiones, muchas veces fundamentadas más en la intuición, fruto de la propia experiencia, que en un análisis estricto, me han dado la razón. Aunque muchas otras me he equivocado. Es conocido el resultado del experimento del chimpancé contra los «expertos» en bolsa y cómo quedó demostrado que los «expertos» se equivocan tanto o más que los «inexpertos». Resultado o conclusión que creo firmemente aplicable a todos los ámbitos, disciplinas e industrias. Las Tecnologías de la Información incluidas. Sin embargo, esta era una de esas veces en que el margen para el error no existía. Nada de intuición, entonces.

Por curiosidad, con la mente en hacer alguna cosilla al modo homebrew [@ Wikipedia] había leído varias cosillas sobre Objective-C [@ Wikipedia], pero no tenía la experiencia suficiente con el lenguaje ni con el SDK de desarrollo para iPhone como para moverme con la rapidez suficiente y garantizar plazos y calidad, dos de los pilares fundamentales para el éxito de los proyectos. No digo que no se pudiera. Simplemente no podía hacer una estimación fiable. No me encontraba cómodo estimando con tantas incógnitas. Así que anduve buscando otras opciones. Y encontré una que me encantó: MonoTouch [Web oficial].

MonoTouch es una pequeña joya de ingeniería que te permite programar en un lenguaje orientado a objetos con tipado fuerte, expresiones lambda [@ Wikipedia] «reducidas» y con recolección de basura, tres de las cosas que más me gustan, como es C#, y compilar a código nativo de iPhone. Para lo cual expone las interioridades de las API's del SDK de iPhone permitiendo que se usen empleando la sintaxis y semántica de C#, pero sin perder de vista cuál es la estructura ni el diseño empleados en el API subyacente. Yo soy (más o menos) experto programando con C#, así que es un lenguaje con el que podría dar más garantías, pese a seguir desconociendo buena parte del diseño del SDK. Habría que confiar en San Google para resolver las dudas que se fueran presentando al respecto.

He subrayado lo de «recolector de basura» porque Objective-C para iPhone te exige que gestiones tú la memoria. Mis recuerdos de experiencias con lenguajes como C y C++ (poca con éste último) me gritaban al oído que la acabaríamos jodiendo a base de bien con memory leaks [@ Wikipedia] y, como decía antes, no existía margen para el error. Y no exagero con esta última afirmación (o negación): No existía. Ni en plazos ni en forma. Y no doy más detalles porque entra dentro de la información privada de la compañía. Tal vez baste reseñar que el proceso de aprobación de aplicaciones y posteriores actualizaciones para publicar una aplicación en la App Store es lento y, aunque se resuelva la incidencia en tiempo récord, se debe esperar varios días hasta que en Apple den nuevamente el visto bueno y se publique la corrección. Al menos es así cómo me lo habían contado y era un factor limitativo a la hora de poner en marcha una aplicación que debía coincidir con otros eventos externos de la compañía contratante. A ver quién es el guapo que les convence de que la «culpa no es tuya» porque Apple no de el visto bueno al arreglo en tiempo límite para que salga publicada la aplicación antes del día que se prefijó. Los plazos eran justos. Demasiado justos. ¿Lo había dicho ya?

¿Alguien recuerda cómo se resolvían los sistemas de ecuaciones con dos incógnitas? «Fijabas» una de ellas, la ponías en función de la otra y sustituías [@ Wikipedia], de forma que convertías el sistema en una ecuación de una única incógnita y resolvías. Siempre que fuese un sistema compatible y determinado, eso sí. Para mí poder fijar el lenguaje a uno que conocía lo suficientemente bien ya era resolver la mitad de la ecuación, por lo que propuse —con vehemencia incluso— realizar una prueba de concepto y medir.

Me costó convencer a los responsables para que me diesen la oportunidad. Siempre que hay desconocimiento hay desconfianza. Aunque nunca termino de entender qué motivos tienen para detestar todo lo que esté relacionado con .NET, pero lo cierto es que cuesta que entiendan que tampoco es tan malo. En cualquier caso conseguí que me dejaran hacer la prueba, que era lo importante. Principalmente porque para la parte de codificación no hacía falta gastarse un euro en licencias.

La prueba fue bastante bien. Diría que todo un éxito. Había lagunas al principio y quedaron lagunas tras la prueba, lógico. Pero estábamos más seguros de que podríamos hacerlo en tiempo y forma. Y eso que para la prueba dedicamos, durante tres días, el equivalente a un desarrollador y medio. Quedé encantado con MonoTouch y lo que me permitía hacer en tan poco tiempo y no teniendo apenas idea de programación para iPhone. Y todo ello incluyendo algunos tests unitarios [@ Wikipedia]. Quería introducir al equipo en las «buenas prácticas». Lástima que de momento el desarrollo ágil [@ Wikipedia] quede completamente fuera de programa.

Para ponerlo aún más complicado decidí que la programación usando las API del SDK de iPhone, la parte de interfaz vamos, la hiciera un compañero. Excelente programador, pero que desconocía .NET. Únicamente programaba en Java. Yo le iba resolviendo las dudas que le iban surgiendo con el lenguaje C#, pero no quería intervenir en el enganche C# (MonoTouch) con el SDK del iPhone. Al menos no mucho. Primero porque tampoco tenía todas las respuestas y, segundo y más importante, porque quería comprobar, medir, si el lenguaje podía ser un contratiempo o facilitar el desarrollo en tiempo límite. ¿Sería tan complejo aprender el lenguaje que ocuparía toda la atención del programador en detrimento de lo «importante», que era el SDK del iPhone? ¿O, por el contrario, y tal como yo defendía, facilitaría el centrarse en las particularidades de CocoaTouch y la suerte de API's que acompañan el SDK de desarrollo para iPhone?

En este punto abro un inciso. Si eres de los que dicen que un lenguaje es «mejor» o «peor» que otro por el simple hecho de que te guste más o menos, aunque tú creas que tus fundamentos son objetivos, te adelanto que por mi te puedes ir a la mierda. No existe ni un solo lenguaje perfecto. Y menos para todos los ámbitos, contextos o circunstancias. De hecho todos son bastante malos porque no me permiten expresar las cosas como me gustaría (lenguaje natural) y únicamente puedo hacerlo con los artefactos sintácticos/semánticos, sintéticos a fin de cuentas, que me facilitan a tal efecto y los patrones de diseño que les apeteció aplicar a los arquitectos de los frameworks que los acompañan. A partir de ahí sí puedo decir que con unos soy más «productivo» que con otros, según los requerimientos. O que con unos me «divierto» más que con otros. Pero al final todo se reduce a lo que yo soy capaz de hacer —o quiero hacer— con un lenguaje determinado. Soy plenamente consciente de la subjetividad de la elección de un lenguaje de programación concreto, así que me la «pela» todo el que viene a evangelizarme proponiendo que su decisión es mejor. Algo parecido me pasa con los sistemas operativos, pero eso lo dejaremos para otra ocasión. Fin del inciso.

Al compañero, acostumbrado a programar en Java, le costó menos de un suspiro familiarizarse con la sintaxis de C# (que diría es en un 99% parecida a la de Java), y apenas unas horas solventar sus tropiezos con las particularidades de .NET. Cierto que es muy bueno —y creo que tendrá un gran futuro en la industria—, pero quería que alguien ajeno a la discusión sobre Java/.NET/Objective-C diese una opinión más objetiva. Argumento que quería usar para defenderme de los detractores de la «curva de aprendizaje» (sospecho que más suave que la requerida para saltar de Java a Objective-C) y que se apoyaban en el argumento «no tenemos aquí a nadie que sepa .NET». Bueno, me tienen a mí. Mientras que expertos en Objective-C, lo que se dice «expertos», no hay muchos más en la compañía. Tal vez se puedan contar con los dedos de una mano de un tipo que ha perdido tres y medio en un accidente.

De mi primera experiencia con MonoTouch y el desarrollo para iPhone con él, me quedé gratamente impresionado. Quedaba la segunda parte: gastar el dinero que costaban la licencia de desarrollador de Apple (100$) y la licencia de MonoTouch (400$), para comprobar qué rendimiento se obtenía en un terminal real. La primera parte de la prueba de concepto se hizo trabajando con el simulador únicamente.

Quinientos dólares no es dinero para una empresa de la envergadura que tiene en la que trabajo. De hecho es apenas dinero para muchas empresas. Haya crisis o no. Dicen que sin riesgo no hay recompensa. Quinientos dólares es un gasto (en realidad una inversión) ridícula si te permite entrar de lleno en la App Store y en el mundo del desarrollo rápido de aplicaciones para iPhone/iPad/iPod Touch. Ya «veía» un futuro cercano con decenas de aplicaciones (más o menos) tontas dispuestas en la App Store avalando nuestro buen hacer como compañía. Un curriculum inmejorable cuando se presentan presupuestos y ofertas con esta tecnología. Tan convencido estaba de mi propuesta (la intuición, una vez más), que no me importó enfrentarme abiertamente a aquellos en la compañía que sienten, digámoslo suavemente, poco aprecio hacia mis opiniones o propuestas. Mi argumentación era sencilla: si sale bien, ganaremos dinero; si sale mal, únicamente perderemos quinientos dólares. Lo que, sinceramente, no es dinero cuando tienes más de cien empleados.

Y, entonces, llegó Apple y me «dio por culo». Y a muchos más. En su batalla contra Adobe nos regaló la cláusula 3.3.1 [Nueva licencia para los desarrolladores de la App Store, Apple cierra el cerco a Adobe @ Applesfera; Apple prohibe a los desarrolladores de iPhone crear aplicaciones con Flash, entre otros @ Appleismo] y todo se vino abajo. Me tuve que tragar mis argumentos porque Apple había decidido convertirme en un «daño colateral». Y los que opinaban que era más fácil/seguro con Objective-C dieron saltos de alegría. Y tanto saltaron que a uno lo han ascendido. Así es la vida.

Mi experiencia con MonoTouch fue hace unos cuatro/cinco meses. Sigo convencido que es una alternativa genial para desarrollar para iPhone, y ahora para iPad también. Aunque sigo teniendo dudas acerca del rendimiento final sobre un terminal. He seguido los avances en relación a la sección maldita y veo que siguen apareciendo aplicaciones desarrolladas con la plataforma .NET [@ MonoTouch Apps]. Se supone que esto no debería estar sucediendo, pero las aplicaciones pasan el control de exigencia y se publican en la App Store. Además, parece que las autoridades estadounidenses no se han tomado muy a bien la redacción de las exigencias [La sección 3.3.1 de Apple, al borde de una investigación de defensa de la competencia @ Appleismo]. No creo que sea para celebrarlo. Todo lo contrario. Creo que Apple es una de las empresas que más y mejor miman a sus consumidores con productos muy fáciles de usar. Una investigación gubernamental no sería buena, supongo. Pero si lo que realmente persiguen es un verdadero control de calidad de los productos que llegan a la App Store tienen muchas formas de hacerlo más allá de determinar qué herramientas usar para ello. Intentaré exponer mi pensamiento a la forma bruta y tradicional con la que suelo expresarme. Para pergeñar una cagada únicamente hace falta un culo. Todos tenemos uno. Los programadores también. Y da igual si cagas detrás de una tabaiba [@ Wikipedia] a plena luz del día o si lo haces en un inodoro fabricado en oro en una suite de lujo del hotel más caro del mundo. La calidad de la mierda está más relacionada con lo que ingiera el programador la persona, que sobre la superficie sobre la qué la deposita cuando caga. Si Apple quiere saber si un mojón será un buen abono para hacer crecer sus beneficios, que al final es lo que les preocupa, que analice la mierda, no el retrete sobre el que se cagó. Y, por suerte, para analizarla existen herramientas y técnicas. Y, si no, las crean, que para eso tienen un departamento de I+D que da envidia a todo cristo viviente. ¿Vale la metáfora?

Mientras espero a que se aclaren las cosas, he tenido la oportunidad de enfrentarme al desarrollo de una aplicación usando Objective-C (a lo que me ayudó haber peleado primero con MonoTouch). Aunque no de la que se hizo un prototipo en MonoTouch, ya que esa al final se «cayó». Quería aprovechar esta experiencia para señalar, en modo de una serie de articulillos, las diferencias que he apreciado. Además, estoy haciendo algunas pruebas con PhoneGap [Web oficial] que también espero poder reflejar en un futuro no muy lejano. Tengo en mente hacer la misma aplicación usando las tres tecnologías y hacer una serie de artículos narrando los toletazos que me vaya dando con cada una:
  1. MonoTouch (cliente) / ASP.NET (servidor)
  2. Objective-C (cliente) / Java (servidor)
  3. JavaScript (cliente) / ? (servidor)

Pero me temo que, para eso, ya empiezo mañana. O pasado. Esta entrada ya ha sido larga en exceso. Así que no la voy a estirar más.