2012-03-29 13 views
5

Staram się stworzyć "klasę nadawców e-maili z narzędziami", którą mogę wykorzystać w kilku projektach iPhone.MFMailComposeViewController w oddzielnej klasie

Utworzono nagłówek i implementację MailSender do tego celu.

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 

Zadzwoniłem do klasy z widoku kontrolera (w przycisku lądować działań) zgodnie z poniższymi instrukcjami:

@implementation InfoViewController 

MailSender *sender; 

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

.... 
@end 

Po uruchomieniu kodu mogę poprawnie wyświetlać widoki wiadomości e-mail. Następuje jednak awaria. Należy zauważyć, że nie mam awarię podczas korzystania MFMailComposeViewController bezpośrednio z mojego UIViewController (I przypisując kontroler widoku jako delegata),

Wszelkie pomysły? Przepraszam, że wciąż jestem nowym celem C :)

+1

Nie widzę problemu w tym kodzie ... powinien działać dobrze !!! po prostu spróbuj clean building/restartowanie xcode. Myślę, że to zawiesza się z innego miejsca. –

+0

Jeśli usunę: mailer.mailComposeDelegate = self; to już się nie psuje! Coś nie tak z moim delegatem? – SiN

+0

O której godzinie ulega awarii? Czy jest to przypadek, gdy metoda delegata 'didFinishWithResult' jest wywoływana? Czy mógłbyś też opublikować kod kontrolera widoku, który wywołuje metodę 'initWithParent'? – Mutix

Odpowiedz

7

Musisz zachować swoją instancję MailSender nadawcy. Zostanie zwolniony po wywołaniu komunikatu invoke.

Możesz to zrobić, deklarując property o nazwie sender. Na przykład.

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

Nawiasem mówiąc, deklaracja metody jest nieco zabawna. Powinieneś nazwać argumenty. Na przykład.

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

Wielkie dzięki, ta praca. Dziękuję również za wskazówki dotyczące deklaracji metody. Mam dwa pytania, których nie wiem, czy możesz mi odpowiedzieć: 1 Jak to się stało, że ARC wypuściło instancję wysyłającą, wiedząc, że nie anulowałem jej? 2 - Dzięki dostarczonemu rozwiązaniu, właściwość * nadawca jest teraz dostępna dla wszystkich klas (ponieważ znajduje się w nagłówku), w dowolny sposób, aby uczynić go prywatnym (implementacja specyficzna, a nie w nagłówku)? Przepraszamy za wszelkie nieporozumienia z mojej strony. – SiN

+1

Został zwolniony, ponieważ nie używałeś go już po wywołaniu komunikatu invoke. Możesz uczynić nieruchomość prywatną, używając kategorii. Zobacz ten link http://stackoverflow.com/questions/172598/best-way-to-define-private-methods-for-a-class-in-objective-c –

+0

Wielkie dzięki Paul – SiN

Powiązane problemy