【发布时间】:2011-03-28 15:52:26
【问题描述】:
如何在不使用任何电子邮件客户端的情况下从 Cocoa 应用程序发送电子邮件?我有 NSURL,但它打开了一个电子邮件客户端。我想在不发生这种情况的情况下发送电子邮件。
【问题讨论】:
标签: objective-c cocoa xcode macos email
如何在不使用任何电子邮件客户端的情况下从 Cocoa 应用程序发送电子邮件?我有 NSURL,但它打开了一个电子邮件客户端。我想在不发生这种情况的情况下发送电子邮件。
【问题讨论】:
标签: objective-c cocoa xcode macos email
那些响应是过时的 Mac OS X 10.8 和更多你应该使用 NSSharingService
NSArray *shareItems=@[body,imageA,imageB];
NSSharingService *service = [NSSharingService sharingServiceNamed:NSSharingServiceNameComposeEmail];
service.delegate = self;
service.recipients=@[@"xxx@apple.com"];
service.subject= [ NSString stringWithFormat:@"%@ %@",NSLocalizedString(@"SLYRunner console",nil),currentDate];
[service performWithItems:shareItems];
【讨论】:
NSSharingService 是 10.8+,但 recipients 和 subject 属性仅是 10.9+,所以如果你的目标是 10.8,你应该添加一个 respondToSelector: 测试。
更新:正如其他人建议的那样,从 10.9 开始,您也可以使用支持附件的 NSSharingService!
Swift 示例:
let emailImage = NSImage.init(named: "ImageToShare")!
let emailBody = "Email Body"
let emailService = NSSharingService.init(named: NSSharingServiceNameComposeEmail)!
emailService.recipients = ["support@myapp.com"]
emailService.subject = "App Support"
if emailService.canPerform(withItems: [emailBody,emailImage]) {
// email can be sent
emailService.perform(withItems: [emailBody,emailImage])
} else {
// email cannot be sent, perhaps no email client is set up
// Show alert with email address and instructions
}
旧更新:我的旧答案运行良好,直到我不得不为 App Store 沙箱化我的应用程序。~~ 从那时起,我发现的唯一解决方案就是使用一个 mailto: 链接。
- (void)sendEmailWithMail:(NSString *) senderAddress Address:(NSString *) toAddress Subject:(NSString *) subject Body:(NSString *) bodyText {
NSString *mailtoAddress = [[NSString stringWithFormat:@"mailto:%@?Subject=%@&body=%@",toAddress,subject,bodyText] stringByReplacingOccurrencesOfString:@" " withString:@"%20"];
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:mailtoAddress]];
NSLog(@"Mailto:%@",mailtoAddress);
}
缺点:没有附件!如果你知道如何让它在 Mac 上运行,请告诉我!
旧答案: 您可以使用 Apple Script、Apple 的脚本桥接框架(解决方案 2)或 Python 脚本(解决方案 3)
解决方案 1(Apple 脚本):
attachments 是一个包含文件路径的字符串数组
- (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");
}
解决方案 2(Apple scriptingbridge 框架):
您可以使用 Apple 的 scriptingbridge 框架来使用 Mail 发送您的消息
Apple's exmaple link 这非常简单,您只需在项目中添加规则和 Mail.app 即可。仔细阅读 Readme.txt。
更改“emailMessage.visible = YES;”到“emailMessage.visible = NO;”所以它会在后台发送它。
缺点:用户需要在Mail下拥有有效账户。
解决方案 3(Python 脚本(无用户帐户):
您还可以使用 python 脚本发送消息。
缺点:用户必须输入 SMTP 详细信息,除非您从 Mail 中获取它们(但是您可以直接使用上面的解决方案 1),或者您必须在您的应用程序中硬编码一个可靠的 SMTP 中继(您可以设置一个 gmail 帐户并使用它为此,如果您的应用程序发送的电子邮件过多,Google 可以删除您的帐户 (SPAM))
我使用这个 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;
}
}
希望对你有帮助
【讨论】:
【讨论】:
您需要使用Simple Mail Transfer Protocol (SMTP)。此链接将为您简要介绍其工作原理:Understanding the SMTP Protocol。
【讨论】: