viernes, 22 de febrero de 2013

Leyes inconstitucionales

Capaz que es un poco ingenuo de mi parte, pero ¿el parlamento no debería asegurarse que las leyes que vota sean constitucionales?

En los últimos días hemos tenido por lo menos dos casos, con el ICIR y la ley interpretativa de la ley de caducidad, que la Suprema Corte de Justicia declara como inconstitucionales leyes que fueron votadas y promulgadas.

Es decir, tenemos un Parlamento con 99 diputados y 30 senadores (o por ahí...), que a su vez tienen secretarios y asistentes varios. ¿No deberían al menos tratar de que las leyes sean constitucionales? ¿Qué sentido tiene que voten leyes que no son válidas?

¿Son tan ignorantes que ni siquiera conocen la constitución? Parece como que debería ser requisito previo para ser diputado o senador, ¿no? Aunque en la realidad esto claramente no aplica...

viernes, 15 de febrero de 2013

Smart App Banners en Mobile Safari

Esta no la sabía, me pareció interesante como para compartirlo.

Aparentemente desde iOS 6, Safari tiene una funcionalidad llamada Smart App Banners, que permite que la página web muestre un banner con un link para bajar o abrir una determinada aplicación.

Del anuncio de Apple:
With Safari’s new Smart App Banner feature in iOS 6, you can display a banner that provides a direct link to your app on the App Store, or opens the app if the user already has it installed. Smart App Banners integrate seamlessly, have the same look and feel users know from the App Store, and are easy to implement.
Agregarlo en una página web cualquiera es muy fácil. Alcanza con agregar un meta-tag en el HTML:
<meta name="apple-itunes-app" content="app-id=529888450">
En ejecución se ve así:


Agregar esto en GeneXus también es muy fácil, alcanza con poner lo siguiente en el evento Start del Web Panel:
Form.Meta.AddItem("apple-itunes-app", "app-id=529888450")
Y por favor, si lo usan, úsenlo bien... No hagan como Quora que bloquea el contenido de la página web para que haya que bajar la aplicación.

lunes, 11 de febrero de 2013

Objective-C: ejecución sincrónica mediante semáforos

En Objective-C, o para ser más precisos en iOS, la norma es que cuando una tarea lleva tiempo, la misma se ejecuta de forma asincrónica mediante el uso de delegates y call-backs.

Por ejemplo, si queremos obtener el contenido de una página web, usamos NSURLConnection. El método start de dicha clase, inicia la operación y termina inmediatamente, antes de comenzar a recibir datos. Los datos llegan a través de los métodos del protocolo NSURLConnectionDelegate, como por ejemplo, connection:didReceiveData:.

Esto presenta un problema para la implementación de las clases estándar de GeneXus, ya que por ejemplo cuando hacemos
&httpClient.execute('GET', 'http://www.google.com')
&status = &httpClient.statusCode
esperamos que al volver de la llamada la variable &status tenga la información correspondiente.

La solución que encontramos para que la ejecución se realice de forma sincrónica, es mediante el uso de semáforos.

Los semáforos son parte de una tecnología llamada Grand Central Dispatch, que está disponible para iOS a partir de la versión 4.0.

La forma de implementar esto es la siguiente:
  1. cuando se llama al método que queremos que ejecute de forma sincrónica, se crea un nuevo semáforo mediante una llamada a la función dispatch_semaphore_create:
    _loadingSemaphore = dispatch_semaphore_create(0);
  2. la operación asincrónica se debe iniciar en otro thread (en particular hay operaciones que necesitan ejecutarse en el main thread), de forma que no haya bloqueos. En el ejemplo del HTTPClient, sería así:
    dispatch_sync(dispatch_get_main_queue(), ^{
      _conn = [NSURLConnection connectionWithRequest:request delegate:self];
      [_conn start];
    });
  3. cuando termina la operación asincrónica, se libera el semáforo de forma que los demás métodos puedan ejecutar:
    dispatch_semaphore_signal(_loadingSemaphore);
  4. mientras tanto, los demás métodos que necesitan que haya terminado la operación para poder ejecutar, como por ejemplo el statusCode, se bloquean hasta que termine la ejecución, luego realizan la tarea que necesitan y por último mandan un nuevo signal al semáforo por si hay alguna otra tarea esperando:
    dispatch_semaphore_wait(_loadingSemaphore, DISPATCH_TIME_FOREVER);
    block();
    dispatch_semaphore_signal(_loadingSemaphore);
Esta forma de implementar la ejecución sincrónica tiene además una ventaja: solo espera cuando es necesario. En el ejemplo, ejecutábamos el método execute e inmediatamente le pedíamos el statusCode, por lo que va a quedar esperando. Pero si antes de pedir el statusCode hacemos otra cosa, como por ejemplo ejecutar un procedimiento, puede ser que al terminar el procedimiento ya hayan venido los datos, y por lo tanto el statusCode no espera.