2009-12-15 51 views
2

我正在使用MFMailComposeViewController從應用程序內發送郵件。我已將Apple示例中的代碼添加到UITableViewController,並且所有按預期工作時,我從UIToolBarButton觸發modalViewController。當我在UIToolBarButtonMFMailComposeViewController代碼之間輸入UIActionSheet時,問題就出現了。使用帶有UIActionSheet的MFMailComposeViewController時發生崩潰

我想向用戶展示通過電子郵件發送或發佈到Facebook的選項。當我解僱UIActionSheet後調用MFMailComposeViewController方法時,我的應用程序在該方法嘗試加載modalViewController時崩潰。代碼如下,有什麼想法?

// UIToolBarButton generates the email string and displays the UIActionSheet with email options 
- (void)onEmailButtonTouch 
{ 
    int mySection; 
    int myRow; 
    emailString = [NSString stringWithFormat:@"<b><p>Ten Essentials Check List</b><br />%@</p>", [myList valueForKey:@"listName"]]; 

    for (mySection = 0; mySection < [[fetchedResultsController sections] count]; mySection ++) 
    { 
     NSString *sectionName = [NSString stringWithFormat:@"<p><b>%@ Group</b></p><ul>", [[[fetchedResultsController sections] objectAtIndex:mySection] name]]; 
     emailString = [emailString stringByAppendingString:sectionName]; 
     id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:mySection]; 

     for (myRow = 0; myRow < [sectionInfo numberOfObjects]; myRow ++) 
     { 
      // Get the managedObject 
      NSIndexPath *indexPath = [NSIndexPath indexPathForRow:myRow inSection:mySection]; 
      NSManagedObject *managedObject = [fetchedResultsController objectAtIndexPath:indexPath]; 

      //Get the related Item object 
      Item *item = [managedObject valueForKey:@"item"]; 
      NSString *itemName = [NSString stringWithFormat:@"<li>%@</li>", item.itemName]; 
      emailString = [emailString stringByAppendingString:itemName]; 
     } 

     emailString = [emailString stringByAppendingString:@"</ul>"]; 
    } 

    NSLog(@"email string = :\n%@", emailString); 
    [self showEmailOptions]; 
} 

// Display an UIActionSheet with email/facebook buttons 
-(void)showEmailOptions 
{ 
    UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"eMail Options" delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle:NULL otherButtonTitles:@"Send List via Email", @"Post List to Facebook", NULL]; 
    [actionSheet showFromToolbar:self.navigationController.toolbar]; 
    [actionSheet release]; 
} 

// Call the MFMailComposeViewController methods if the user selects the Email button of the actioSheet 
- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex 
{ 
    if (buttonIndex == 0) 
    { 
     NSLog(@"Opening email"); 
     [self showPicker]; 
    } 
} 


-(void)showPicker 
{ 
    // This sample can run on devices running iPhone OS 2.0 or later 
    // The MFMailComposeViewController class is only available in iPhone OS 3.0 or later. 
    // So, we must verify the existence of the above class and provide a workaround for devices running 
    // earlier versions of the iPhone OS. 
    // We display an email composition interface if MFMailComposeViewController exists and the device can send emails. 
    // We launch the Mail application on the device, otherwise. 

    Class mailClass = (NSClassFromString(@"MFMailComposeViewController")); 
    if (mailClass != nil) 
    { 
     // We must always check whether the current device is configured for sending emails 
     if ([mailClass canSendMail]) 
     { 
      [self displayComposerSheet]; 
     } 
     else 
     { 
      [self launchMailAppOnDevice]; 
     } 
    } 
    else 
    { 
     [self launchMailAppOnDevice]; 
    } 
} 


// Displays an email composition interface inside the application. Populates all the Mail fields. 
-(void)displayComposerSheet 
{ 
    MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init]; 
    picker.mailComposeDelegate = self; 
    [picker setSubject:@"Here is your gear check list!"]; 

    // Attach an image to the email 
    NSString *path = [[NSBundle mainBundle] pathForResource:@"Checkmark_icon" ofType:@"png"]; 
    NSData *myData = [NSData dataWithContentsOfFile:path]; 
    [picker addAttachmentData:myData mimeType:@"image/png" fileName:@"Checkmark_icon"]; 

    // Fill out the email body text 
    NSString *emailBody = emailString; 
    [picker setMessageBody:emailBody isHTML:YES]; 

    // CRASH HAPPENS ON THE LINE BELOW // 
    [self presentModalViewController:picker animated:YES]; 
    [picker release]; 
} 


// Dismisses the email composition interface when users tap Cancel or Send. Proceeds to update the message field with the result of the operation. 
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error 
{ 
    //message.hidden = NO; 
    // Notifies users about errors associated with the interface 
    switch (result) 
    { 
     case MFMailComposeResultCancelled: 
      NSLog (@"Result: canceled"); 
      break; 
     case MFMailComposeResultSaved: 
      NSLog (@"Result: saved"); 
      break; 
     case MFMailComposeResultSent: 
      NSLog (@"Result: sent"); 
      break; 
     case MFMailComposeResultFailed: 
      NSLog (@"Result: failed"); 
      break; 
     default: 
      NSLog (@"Result: not sent"); 
      break; 
    } 

    [self dismissModalViewControllerAnimated:YES]; 
} 


#pragma mark - 
#pragma mark Workaround 
// Launches the Mail application on the device. 
-(void)launchMailAppOnDevice 
{ 
    NSString *recipients = @"mailto:[email protected][email protected],[email protected]&subject=Here is your gear check list!"; 
    NSString *body = emailString; 
    NSString *email = [NSString stringWithFormat:@"%@%@", recipients, body]; 
    email = [email stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 

    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:email]]; 
} 
+0

更新這個...其他職位也有同樣的問題,看到這個線程: http://stackoverflow.com/questions/1082954/presentmodalviewcontroller-crashes-my-app 試過推遲選擇,但它不適合我。 Jk – Alpinista 2009-12-15 02:09:48

回答

1

實際上,大衛(以上評論)讓我走上了正軌。 UIActionSheet導致我的emailString ivar無效,所以我在調用UIActionSheet之前先調用emailString。現在所有人都在工作!

1

我覺得你的問題是,你需要

[emailString retain]; 

它是一個自動釋放的對象,我想以後onEmailButtonTouch回到它變得釋放,因此,它是當你的警報通知火災無效。

+0

emailString是一個伊娃,所以不會釋放,直到VC被釋放爲止 Jk – Alpinista 2009-12-15 17:07:40

+1

如果它是一個標記爲(保留)的屬性,那麼這將是這種情況,但那麼您需要將其稱爲self.emailString當你做了任務。事實上,它不會自動保留給你。 – 2009-12-15 17:23:06