Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Send Email - Cocoa [closed]

Tags:

email

macos

cocoa

How would I be able to send emails using Cocoa? Which framework would I use, and how would I use it.

like image 263
lab12 Avatar asked Sep 08 '09 20:09

lab12


4 Answers

I think using an Apple script is the simplest solutions. I use it when the user has an account set up in Mail.

Apple script:

attachments is an array of stings containing file paths.

"set visible to true" if you want the message to pop up before sending

- (void)sendEmailWithMail:(NSString *) toAddress withSubject:(NSString *) subject Attachments:(NSArray *) attachments { 
NSString *bodyText = @"Your body text \n\r";    
NSString *emailString = [NSString stringWithFormat:@"\
                         tell application \"Mail\"\n\
                         set newMessage to make new outgoing message with properties {subject:\"%@\", content:\"%@\" & return} \n\
                         tell newMessage\n\
                         set visible to false\n\
                         set sender to \"%@\"\n\
                         make new to recipient at end of to recipients with properties {name:\"%@\", address:\"%@\"}\n\
                         tell content\n\
                         ",subject, bodyText, @"McAlarm alert", @"McAlarm User", toAddress ];

//add attachments to script
for (NSString *alarmPhoto in attachments) {
    emailString = [emailString stringByAppendingFormat:@"make new attachment with properties {file name:\"%@\"} at after the last paragraph\n\
                   ",alarmPhoto];

}
//finish script
emailString = [emailString stringByAppendingFormat:@"\
               end tell\n\
               send\n\
               end tell\n\
               end tell"];



//NSLog(@"%@",emailString);
NSAppleScript *emailScript = [[NSAppleScript alloc] initWithSource:emailString];
[emailScript executeAndReturnError:nil];
[emailScript release];

/* send the message */
NSLog(@"Message passed to Mail");

}

Disadvantage: users need to have valid accounts under Mail.

Python Script (if no user account under mail): You can also use a python script to send a message. Disadvantage: users have to enter SMTP details unless you grab them from Mail (but then you can use the apple script above ), or you have to have a reliable SMTP relay hardcoded in your app (you can set up a gmail account and use it for that purpose, however if your apps send too many emails google can delete your account (SPAM))
I use this python script:

import sys
import smtplib
import os
import optparse

from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email.Utils import COMMASPACE, formatdate
from email import Encoders

username = sys.argv[1]
hostname = sys.argv[2]
port = sys.argv[3]
from_addr = sys.argv[4]
to_addr = sys.argv[5]
subject = sys.argv[6]
text = sys.argv[7]

password = getpass.getpass() if sys.stdin.isatty() else sys.stdin.readline().rstrip('\n')

message = MIMEMultipart()
message['From'] = from_addr
message['To'] = to_addr
message['Date'] = formatdate(localtime=True)
message['Subject'] = subject
#message['Cc'] = COMMASPACE.join(cc)
message.attach(MIMEText(text))

i = 0
for file in sys.argv:
    if i > 7:
        part = MIMEBase('application', 'octet-stream')
        part.set_payload(open(file, 'rb').read())
        Encoders.encode_base64(part)
        part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(file))
        message.attach(part)
    i = i + 1

smtp = smtplib.SMTP(hostname,port)
smtp.starttls()
smtp.login(username, password)
del password

smtp.sendmail(from_addr, to_addr, message.as_string())
smtp.close()

And I call it form this method to send an email using a gmail account

- (bool) sendEmail:(NSTask *) task toAddress:(NSString *) toAddress withSubject:(NSString *) subject Attachments:(NSArray *) attachments {

        NSLog(@"Trying to send email message");
        //set arguments including attachments
        NSString *username = @"[email protected]";
        NSString *hostname = @"smtp.gmail.com";
        NSString *port = @"587";
        NSString *fromAddress = @"[email protected]";  
        NSString *bodyText = @"Body text \n\r"; 
        NSMutableArray *arguments = [NSMutableArray arrayWithObjects:
                                    programPath,
                                    username,
                                    hostname,
                                    port, 
                                    fromAddress, 
                                    toAddress,
                                    subject,
                                    bodyText, 
                                    nil];  
        for (int i = 0; i < [attachments count]; i++) {
            [arguments addObject:[attachments objectAtIndex:i]];
        }

        NSData *passwordData = [@"myGmailPassword" dataUsingEncoding:NSUTF8StringEncoding];


        NSDictionary *environment = [NSDictionary dictionaryWithObjectsAndKeys:
                                     @"", @"PYTHONPATH",
                                     @"/bin:/usr/bin:/usr/local/bin", @"PATH",
                                     nil];
        [task setEnvironment:environment];
        [task setLaunchPath:@"/usr/bin/python"];

        [task setArguments:arguments];

        NSPipe *stdinPipe = [NSPipe pipe];
        [task setStandardInput:stdinPipe];

        [task launch];

        [[stdinPipe fileHandleForReading] closeFile];
        NSFileHandle *stdinFH = [stdinPipe fileHandleForWriting];
        [stdinFH writeData:passwordData];
        [stdinFH writeData:[@"\n" dataUsingEncoding:NSUTF8StringEncoding]];
        [stdinFH writeData:[@"Description" dataUsingEncoding:NSUTF8StringEncoding]];
        [stdinFH closeFile];

        [task waitUntilExit];

        if ([task terminationStatus] == 0) { 
            NSLog(@"Message successfully sent");
            return YES;
        } else {
            NSLog(@"Message not sent");
            return NO;
        }
    }

I hope it helps

like image 77
Tibidabo Avatar answered Oct 17 '22 04:10

Tibidabo


Apple's Developer Connection has a sample project called SBSendEmail which demonstrates how to use a Scripting Bridge to send email via scripting to the Mail app.

You can download the whole project and run it in XCode to see how it works. Of particular interest to you will be the sendEmailMessage: method in Controller.m

like image 35
Brandon Bodnar Avatar answered Oct 17 '22 03:10

Brandon Bodnar


You can use opening the default mail client or you can use a framework. This should get you started.

like image 4
Garrett Avatar answered Oct 17 '22 05:10

Garrett


For Growl 1.2, I wrote a Python-based mail-sending program, which the MailMe display runs using NSTask.

I did this largely out of dissatisfaction with the other mail frameworks for Cocoa, most of which also support receiving mail, which is unnecessary for something output-only like MailMe.

like image 2
Peter Hosey Avatar answered Oct 17 '22 03:10

Peter Hosey