Проблема MFMailComposeViewController - PullRequest
0 голосов
/ 16 декабря 2009

Эта проблема, вероятно, не относится только к MFMailComposeViewController, но именно здесь у меня проблема ...

  • Я строю NSString myEmailString для сообщения MFMailComposeViewController и хранить его в iVar, прежде чем отображение MFMailComposeViewController в качестве контроллер модального вида.

  • Я передаю строку в MFMailComposeViewController, затем представляю ее как контроллер модального представления.

  • Когда контроллер модального вида закрывается, мой iVar становится недействительным,
    и приложение вылетает, когда я выпускаю emailString iVar в dealloc

Код ниже, что я делаю не так?

-(void)buildEmailMessage {
int mySection;
int myRow;
NSString *buildString = [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]];
    buildString = [buildString 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];
        buildString = [buildString stringByAppendingString:itemName];

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


myEmailString = [NSString stringWithString:buildString];
NSLog(@"email string = :\n%@", myEmailString);
[self showPicker];
}



#pragma mark -
#pragma mark Send Mail

-(void)showPicker {
// This code 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.

NSLog(@"Checking OS for MFMailComposeViewController");

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.navigationBar.barStyle = UIBarStyleBlack;


[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
//***** NOTE: This is where I pass the value from my iVar ***** 
//      into the MFMailComposeViewController
// 
NSString *emailBody = [NSString stringWithString:myEmailString];
[picker setMessageBody:emailBody isHTML:YES];
NSLog (@"DIsplaying Composer Sheet");

[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];

// ***** NOTE: Line below was added to fix the invalid iVar problem *****
myEmailString = @"";
}


#pragma mark -
#pragma mark Workaround

// Launches the Mail application on the device.
-(void)launchMailAppOnDevice {
NSString *recipients = @"mailto:first@example.com?cc=second@example.com,third@example.com&subject=Here is your gear check list!";
NSString *body = myEmailString;

NSString *email = [NSString stringWithFormat:@"%@%@", recipients, body];
email = [email stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

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

- (void)dealloc {
[managedObjectContext release];
[fetchedResultsController release];
[tableview release];
[myList release];
[myEmailString release];

[super dealloc];
}

Ответы [ 4 ]

3 голосов
/ 16 декабря 2009

как объявлен ваш ивар? это объявлено как собственность? в любом случае, он не сохраняется автоматически для вас.

Либо вам нужно сделать

myEmailString = [[NSString stringWithString:buildString] retain];

или

self.myEmailString = [NSString stringWithString:buildString];

если myEmailString объявлен как

@property (nonatomic, retain) NSString *myEmailString

Подумайте об этом: если бы все ивары были автоматически сохранены для вас, то как бы вы получили переменную, которую вы не хотели бы сохранить? Вот почему это не работает.

1 голос
/ 16 декабря 2009

Вы должны сохранить свою строку перед сохранением в iVar:

myEmailString = [[NSString stringWithString:buildString] retain];

Без него он становится недействительным из-за его автоматического освобождения позже во время выполнения вашей программы. Это также гарантирует, что оно будет выделяться при вызове вашего деструктора, предотвращая сбой выпуска.

1 голос
/ 16 декабря 2009

stringWithString: создает новую строку и автоматически высвобождает ее перед возвратом к вам. Если вы не сохраните возвращенную строку, вам не нужно освобождать ее в вашем методе dealloc.

1 голос
/ 16 декабря 2009

когда вы создаете строку myEmail в buildEmailMessage, вы никогда не сохраняете строку. Таким образом, после выхода из функции она автоматически освобождается. Тогда ваш счет сохранения при вызове dealloc будет равен 0, что приведет к сбою. Если вы хотите сохранить переменную, вам нужно иметь следующую строку

myEmailString = [[NSString stringWithString:buildString] retain];

тогда вы можете звонить [myEmailString release] безопасно

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...