发送电子邮件 - Cocoa

5
我该如何使用Cocoa发送电子邮件?我需要使用哪个框架,以及如何使用它。
5个回答

15

我认为使用Apple脚本是最简单的解决方案。当用户在Mail中设置了帐户时,我会使用它。

Apple脚本:

attachments是包含文件路径的字符串数组。

如果你想在发送之前弹出消息,使用"set visible to true"。

- (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");

}

缺点:用户需要在Mail下拥有有效账户。

Python脚本(如果没有在Mail下的用户账户): 您也可以使用Python脚本发送消息。 缺点:用户必须输入SMTP详情,除非您从Mail中获取它们(但然后您可以使用上面的Apple脚本),或者您必须在您的应用程序中硬编码一个可靠的SMTP中继(您可以设置一个Gmail帐户并用于此目的,但是如果您的应用程序发送太多电子邮件,Google可能会删除您的帐户(垃圾邮件)) 我使用这个Python脚本:

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()

我使用这个方法调用它来使用Gmail帐户发送电子邮件。

- (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 = @"my.gmail.account@gmail.com";
        NSString *hostname = @"smtp.gmail.com";
        NSString *port = @"587";
        NSString *fromAddress = @"my.gmail.account@gmail.com";  
        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;
        }
    }

希望它有所帮助


我尝试了你的代码,但问题是,当您启动它时,它会显示程序路径未定义。现在,我已经使用NSString将其设置为我的程序路径,但仍然无法正常工作...我该怎么办? - Izac Mac
这是脚本的路径,定义为:programPath = [[[NSBundle bundleForClass:[self class]] pathForResource:@"emailSender" ofType:@"py"] copy]; - Tibidabo
我在我的项目中添加了Python的资源代码,命名为emailSender.py。还编写了代码NSBundle * programPath = [[[NSBundle bundleForClass:[self class]] pathForResource:@“emailSender” ofType:@“py”] copy]; 所有错误都消失了,但没有发送电子邮件。控制台显示以下详细信息。请帮忙!!! - Izac Mac
2012年02月15日14:42:39.897 mailSend[5582:a0f] 尝试发送电子邮件消息 文件“/Users/myMac/mailSend/build/Debug/mailSend.app/Contents/Resources/emailSender.py”,第1行 {\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf350 ^ 语法错误:意外的字符在行继续字符之后 2012年02月15日14:42:39.972 mailSend[5582:a0f] 消息未发送 2012年02月15日14:42:39.974 mailSend[5582:a0f] 邮件未发送 - Izac Mac
第二个解决方案对我非常有效,所以谢谢!我遇到的唯一问题是示例Python代码需要导入getpass。 - D.C.
我甚至没有意识到AppleScript的存在!这帮助我在Mono Mac应用程序中发送电子邮件。对于任何感兴趣的人,我使用了这个漂亮的小库。链接 - James

8

苹果的开发者连接有一个名为SBSendEmail的示例项目,它演示了如何使用脚本桥接通过脚本向邮件应用程序发送电子邮件。

你可以下载整个项目并在XCode中运行它以了解其工作原理。特别值得注意的是Controller.m中的sendEmailMessage:方法。


5
请注意,在沙盒应用程序中不允许使用Scripting Bridge。 - jemeshsu
这不是真的;你可以使用正确的授权来使用脚本桥接。 - Z S

4
你可以使用默认的邮件客户端或者你可以使用一个框架。这应该能帮助你开始。

两个都对我不起作用。有人可以给我一个例子吗?很抱歉,我非常新手。 - lab12
你是在开发 iPhone 还是桌面应用? - Garrett
我正在使用Xcode 3.2在桌面上进行开发。 - lab12
如果你正在为桌面开发,那么除了桌面之外,你无法在其他地方进行开发。如果你尝试这两个链接,它们会非常有效。 - Garrett
请注意,它们都包含可复制粘贴并运行以获得所需结果的代码,它们都能正常工作。 - Garrett

2
对于Growl 1.2,我编写了一个基于Python的邮件发送程序(链接),MailMe显示器使用NSTask运行该程序。
我这样做主要是因为对Cocoa的其他邮件框架不满意,其中大多数也支持接收邮件,而像MailMe这样仅输出的程序并不需要接收邮件的功能。

0

请查看:

http://www.collaboration-world.com/pantomime

我已经好几年没看过它了,但当我在苹果公司时,我曾主张将其包含在操作系统中,以取代我们在NeXT/Apple转换中失去的邮件功能。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接