2012-03-29 10 views
5

Ich möchte eine "Dienstprogramm E-Mail-Absender-Klasse" erstellen, die ich in mehreren iPhone-Projekten verwenden kann.MFMailComposeViewController in einer separaten Klasse

Ich habe MailSender Header und Implementierung für diesen Zweck erstellt.

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 

ich die Klasse von einem View-Controller genannt (in einer Schaltfläche Aktion aufzusetzen) mithilfe der folgenden Anweisungen:

@implementation InfoViewController 

MailSender *sender; 

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

.... 
@end 

Wenn ich den Code ausführen, kann ich die E-Mail-Ansichten korrekt anzeigen. Dann folgt jedoch ein Absturz. Beachten Sie, dass ich keinen Absturz habe, wenn MFMailComposeViewController direkt von meinem UIViewController verwendet wird (und den View Controller als Delegierten zuweist),

Irgendwelche Ideen? Entschuldigung, ich bin immer noch ein neues Ziel C :)

+1

ich sehe kein Problem in diesem Code ... sollte gut funktionieren !!! Versuchen Sie einfach, xcode zu erstellen/neu zu starten. Ich denke, es stürzt von woanders ab. –

+0

Wenn ich entferne: mailer.mailComposeDelegate = self; es stürzt nicht mehr ab! Irgendetwas stimmt nicht mit meinem Delegierten? – SiN

+0

Zu welcher Zeit stürzt es ab? Ist es, wenn die Delegiertenmethode 'didFinishWithResult' zufällig aufgerufen wird? Könnten Sie auch den Code Ihres View Controllers posten, der die 'initWithParent' Methode aufruft? – Mutix

Antwort

7

Sie müssen Ihre MailSender-Sender-Instanz beibehalten. Es wird freigegeben, nachdem Sie die Aufrufnachricht aufrufen.

Sie könnten dies tun, indem Sie eine property namens sender. Z.B.

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

By the way, ist Ihre Methode Erklärung ein bisschen komisch. Sie sollten die Argumente benennen. Z.B.

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

Vielen Dank, diese Arbeit. Danke auch für Ihre Hinweise zur Methodendeklaration. Ich habe zwei Fragen, die ich nicht kenne, wenn Sie mir antworten können: 1- Wie kommt es, dass die ARK die Senderinstanz freigab, obwohl ich wusste, dass ich sie nicht annullierte? 2- Mit der von Ihnen bereitgestellten Lösung ist die Eigenschaft * sender nun für alle Klassen zugänglich (da sie in der Kopfzeile enthalten ist), wie auch immer, um sie privat zu machen (implementierungsspezifisch und nicht in der Kopfzeile)? Entschuldigung für irgendein Missverständnis von meiner Seite. – SiN

+1

Es wurde veröffentlicht, weil Sie es nicht mehr verwendet haben, nachdem Sie die Aufrufnachricht aufgerufen haben. Sie können die Eigenschaft privat machen, indem Sie eine Kategorie verwenden. Siehe diesen Link http://stackoverflow.com/questions/172598/best-way-to-define-private-methods-for-a-class-in-objective-c –

+0

Vielen Dank Paul – SiN

Verwandte Themen