Desarrollo iOS: AlertMessage, una forma de mejorar UIAlertView

La primera vez que vi la clase UIAlertView se me paralizó la respiración. Miré la documentación oficial, busqué snippets de código por internet… y sí, era así nomas. No podía creer que para poner un simple mensaje que tuviera un par OK/Cancel, tenía que dividir mi código en 2 partes!, es que para enterarme si el usuario presiono un botón u otro hay que colgarse de un delegate. Yo entiendo, tiene toda la lógica, pero tener que separar algo que naturalmente va junto, no me gusta nada. Y la cosa empeora si hay más de un Alert en nuestro Controller: el resultado de cada uno de ellos llega a la misma función del delegate, por lo cual, algo que es feo de por sí, termina siendo además caótico!

Eran tiempos de iOS 3 y no se me ocurrió una buena forma de mejorarlo. Pero con iOS 4 y los code-blocks, la solución llegó. Por eso les presento un wrapper llamado AlertMessage, que soluciona los dos problemas que no me dejaban dormir:

  1. código compacto: el código a ejecutar luego del alerta se define en el mismo lugar donde se crea el AlertMessage y no en otro lugar.
  2. no hay “bolsa de gatos”: no hay un delegate centralizado donde caen todos los Alertas, porque no hay más delegate que programar!

Este es el forma de usar AlertMessage:

  • creo el objeto
  • le asigno título y mensaje
  • le defino los botones
  • le defino el código que debe ejecutarse al momento en que se presionen cualquier de los botones
  • listo, momento de visualizar el Alert: show
  • Asi de simple. Les copio el .h y .m para que puedan probarlo y mejorarlo.

    AlertMessage.h

    //

    // AlertMessage.h

    //

    #import <Foundation/Foundation.h>

    typedef void (^AlertMessageHandler)(int);

    @interface AlertMessage : NSObject

    @property (nonatomic, retain) NSString* titulo;

    @property (nonatomic, retain) NSString* mensaje;

    + (id)alertMessage;

    – (void)show;

    – (void)agregarBoton:(NSString*)_texto;

    – (void)ejecutarCodigo:(AlertMessageHandler)_codigo;

    @end

    AlertMessage.m

    //

    // AlertMessage.m

    //

    #import “AlertMessage.h”

    @interface AlertMessage () <UIAlertViewDelegate>

    {

    UIAlertView* alert;

    AlertMessageHandler codigo;

    }

    – (id)init;

    @end

    @implementation AlertMessage

    @synthesize titulo, mensaje;

    – (void)dealloc

    {

    self.titulo = nil;

    self.mensaje = nil;

    Block_release(codigo);

    [alert release];

    [super dealloc];

    }

    // Para el usuario, AlertMessage tiene una semantica similar a un autorelease: lo construye pero nunca lo mata. En realidad esto lo consigo suicidándolo en el delegate

    // Debido a esto, el Code Analizer reporta un posible leak, asi que uso esta directiva para evitar que analice este método

    #ifndef __clang_analyzer__

    +(id)alertMessage;

    {

    return [[AlertMessage alloc] init]; // no hago autorelease, porque se “suicida” en el delegate

    }

    #endif

    -(id)init;

    {

    self = [super init];

    if (self) {

    alert = [[UIAlertView alloc] init];

    alert.delegate = self;

    }

    return self;

    }

    // aquí termino de completar el UIAlertView y lo displayo

    -(void)show;

    {

    alert.title = self.titulo;

    alert.message = self.mensaje;

    [alert show];

    }

    // delego en addButtonWithTitle

    -(void)agregarBoton:(NSString*)_texto;

    {

    [alert addButtonWithTitle:_texto];

    }

    // me quedo con la instancia de codigo a ejecutar cuando se cierra el UIAlertView

    – (void)ejecutarCodigo:(AlertMessageHandler)_codigo;

    {

    codigo = Block_copy(_codigo);

    }

    #pragma mark –

    #pragma mark Alert view delegate

    – (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {

    // si hay codigo a ejecutar, lo hago

    if (codigo) {

    codigo(buttonIndex);

    }

    [self release]; // aquí se mata a si mismo

    }

    @end

    Entre las mejoras, se me ocurren:

  • crear varios constructores, considerando los usos más habituales, como alertMessageWithOKCancel, etc. etc.
  • soporte para la propiedad cancelButtonIndex de UIAlertView
  • soporte en iOS 5 de la propiedad alertViewStyle de UIAlertView (propiedad muy interesante, que da la interfaz para poner un campo de texto en el alerta, algo que tarde o temprano vas a necesitar).
  • Hasta la próxima!

    Un artículo de Angel Traversi

    0 0 votos
    Article Rating
    Subscribe
    Notify of
    0 Comments
    Opiniones Inline
    Ver todos los comentarios

    Lost your password? Please enter your email address. You will receive mail with link to set new password.

    wpDiscuz
    0
    0
    Me encantaría saber tu opinión, por favor, deja un comentariox
    ()
    x
    Salir de la versión móvil