从Cocoa发送电子邮件 [英] Send email from Cocoa

查看:334
本文介绍了从Cocoa发送电子邮件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何从Cocoa应用程式传送电子邮件,而不使用任何电子邮件用户端?我有NSURL,但它打开一个电子邮件客户端。

How can I send an email from a Cocoa app without using any email clients ? I have NSURL but it opens up an email client. I would like to send the email without this happening.

推荐答案

更新:正如其他人所建议的,从 10.9 您可以使用支持附件的 NSSharingService

UPDATE: As others suggested, from 10.9 you can use NSSharingService that supports attachments as well!

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

    }


旧版更新:我的旧答案工作正常,直到我必须为我的应用商店沙箱我的应用程序~~
从那时起,我找到的唯一解决方案只使用一个mailto:链接。

OLD UPDATE: My old answers worked fine until I had to sandbox my apps for the App Store.~~ Since then the only solution I found was using simply a mailto: link.

- (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上工作让我知道!

Disadvantage: No attachment! If you know how to make it work on Mac let me know!

老问答:
你可以Apple脚本桥梁框架(解决方案2)或Python脚本(解决方案3)

OLD ANSWER: You can Apple Script, Apple's scripting bridge framework (Solution 2) or a Python script (Solution 3)

解决方案1(Apple脚本):

Solution 1 (Apple script):

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

attachments is an array of stings containing file paths

- (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框架使用Mail发送您的邮件

苹果的示例链接这很简单,你只需要干脆向你的项目添加规则和Mail.app。仔细阅读Readme.txt。

Solution 2 (Apple scriptingbridge framework): You can use Apple's scriptingbridge framework to use Mail to send your message
Apple's exmaple link it's pretty straightforward, you only need to fiddle with adding a rule and Mail.app to your project. Read Readme.txt carefully.

更改emailMessage.visible = YES;到emailMessage.visible = NO;因此它会在后台发送。

Change "emailMessage.visible = YES;" to "emailMessage.visible = NO;" so it sends it in the background.

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

Disadvantage: users need to have valid accounts under Mail.

解决方案3(Python脚本(无用户帐户):
也可以使用python脚本发送消息
缺点:用户必须输入SMTP详细信息,除非您从Mail抓取它们(但是您可以使用解决方案1直接),或者你必须有一个可靠的SMTP中继硬编码在你的应用程序(你可以设置一个gmail帐户,并使用它的目的,但如果你的应用程序发送太多的电子邮件google可以删除你的帐户(垃圾邮件) )

我使用这个python脚本:

Solution 3 (Python Script (no user account): 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 Solution 1 above directly), 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()

我使用gmail帐户发送电子邮件,形成这个方法。

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 = @"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;
        }
    }

我希望它有助于

I hope it helps

这篇关于从Cocoa发送电子邮件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆