2012-03-29 8 views
5

Intento crear una "clase de remitente de correo electrónico de utilidad" que pueda usar en varios proyectos de iPhone.MFMailComposeViewController en una clase separada

Creé el encabezado y la implementación de MailSender para tal fin.

MailSender.h:

@interface MailSender : NSObject<MFMailComposeViewControllerDelegate> 

- (id) initWithParent:(UIViewController*) mainController; 

- (void) invokeMailSender:(NSString*) to:(NSString*) subject:(NSString*) failureTitle:(NSString*) failureMessage:(NSString*) failureCancel; 

@end 

MailSender.m:

#import "MailSender.h" 

@implementation MailSender 

MFMailComposeViewController* mailer; 
UIViewController* mailParentController; 

- (id) initWithParent:(UIViewController*) mainController 
{ 
    if(self = [super init]) 
    { 
     mailParentController = mainController; 
    } 
    return self; 
} 

- (void) invokeMailSender:(NSString*) to:(NSString*) subject:(NSString*) failureTitle:(NSString*) failureMessage:(NSString*) failureCancel; 

{ 
    if([MFMailComposeViewController canSendMail]) 
    { 
     mailer = [[MFMailComposeViewController alloc] init]; 

     mailer.mailComposeDelegate = self; 

     [mailer setSubject:subject]; 

     NSArray *toRecipients = [NSArray arrayWithObjects:to, nil]; 

     [mailer setToRecipients:toRecipients]; 
     [mailParentController presentModalViewController:mailer animated:YES]; 
    } 
    else 
    { 
     UIAlertView* alert = [[UIAlertView alloc] initWithTitle:failureTitle message:failureMessage 
                 delegate:nil cancelButtonTitle:failureCancel otherButtonTitles: nil]; 

     [alert show]; 
    } 
} 

-(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error 
{ 
    // Do nothing 
    [mailParentController dismissModalViewControllerAnimated:YES]; 
    mailer = nil; 
} 



@end 

Llamé a la clase de un controlador de vista (en un botón de acción de tocar tierra) utilizando las siguientes instrucciones:

@implementation InfoViewController 

MailSender *sender; 

- (IBAction)openMail:(id)sender 
{ 
    sender = [[MailSender alloc] initWithParent:self]; 
    [sender invokeMailSender:@"[email protected]" :@"123" :@"123" :@"123" :@"123"]; 
} 

.... 
@end 

Cuando ejecuto el código, puedo mostrar las vistas de correo electrónico correctamente. Sin embargo, esto es seguido por un bloqueo. Tenga en cuenta que no tengo un bloqueo cuando uso MFMailComposeViewController directamente desde mi UIViewController (y asignando el controlador de visualización como el delegado),

¿Alguna idea? Lo siento, sigo siendo un nuevo en Objective C :)

+1

i no veo ningún problema en este código ... debería funcionar bien !!! solo intente limpiar la construcción/reiniciar xcode. Creo que está cayendo desde otro lugar. –

+0

Si elimino: mailer.mailComposeDelegate = self; ya no se cuelga! ¿Hay algún problema con mi delegado? – SiN

+0

¿A qué hora se cuelga? ¿Es cuando se llama al método delegado 'didFinishWithResult' por casualidad? ¿También podría publicar el código de su controlador de vista que llama al método 'initWithParent'? – Mutix

Respuesta

7

Debe conservar su instancia de MailSender del remitente. Se lanzará después de llamar al mensaje de invocación.

Puede hacer esto declarando property con el nombre sender. P.ej.

@property (strong, nonatomic) MailSender *sender; 
... 
@synthesize sender = _sender; 
... 
self.sender = [[MailSender alloc] initWithParent:self]; 
[self.sender invokeMailSender:@"[email protected]" :@"123" :@"123" :@"123" :@"123"]; 

Por cierto, la declaración de su método es un poco graciosa. Debes nombrar los argumentos. P.ej.

- (void)invokeMailSender:(NSString *)sender 
         to:(NSString *)to 
       subject:(NSString *)subject 
      failureTitle:(NSString *)failureTitle 
      failureMessage:(NSString *)failureMessage 
failureCancelButtonTitle:(NSString *)failureCancelButtonTitle 
+0

Muchas gracias, ese trabajo. Gracias también por sus sugerencias para la declaración de método. Tengo dos preguntas que no sé si me pueden responder: 1- ¿Cómo es que el ARC estaba liberando la instancia del remitente sabiendo que no la anulé? 2- Con la solución que proporcionó, el remitente de la propiedad * ahora es accesible para todas las clases (ya que está en el encabezado), de cualquier forma para hacerlo privado (específico de la implementación y no en el encabezado)? Perdón por cualquier idea errónea de mi parte. – SiN

+1

Se estaba liberando porque ya no lo usaba después de haber llamado al mensaje de invocación. Puede hacer que la propiedad sea privada mediante el uso de una categoría. Ver este enlace http://stackoverflow.com/questions/172598/best-way-to-define-private-methods-for-a-class-in-objective-c –

+0

Muchas gracias Paul – SiN

Cuestiones relacionadas