2011-03-28 74 views
12

如何在不使用任何電子郵件客戶端的情況下從Cocoa應用程序發送電子郵件?我有NSURL,但它打開了一個電子郵件客戶端。我想在沒有發生這種情況的情況下發送電子郵件。發送可可電子郵件

+0

可能重複=過時。發送和接收郵件框架](http://stackoverflow.com/questions/3567251/pantomime-outdated-sending-and-receiving-mail-framework) – 2011-03-28 16:19:07

+0

可能重複的[Send Email - Cocoa](http:// stackoverflow。 com/questions/1396229/send-email-cocoa) – 2011-05-15 07:42:22

回答

24

更新:正如其他人建議,從10.9可以使用NSSharingService支持附件以及!

斯威夫特例如:

let emailImage   = NSImage.init(named: "ImageToShare")! 
    let emailBody   = "Email Body" 
    let emailService  = NSSharingService.init(named: NSSharingServiceNameComposeEmail)! 
    emailService.recipients = ["[email protected]"] 
    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上工作,讓我知道!

OLD答: 您可以在Apple腳本,蘋果的腳本橋框架(方案二)或Python腳本(方案三)

解決方案1(蘋果腳本):

附件是一個數組包含文件路徑刺

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

}

SOLU您可以使用Apple的scriptingbridge框架使用Mail發送您的消息
Apple's exmaple link這很簡單,您只需要添加一條規則和Mail.app到您的項目中。仔細閱讀Readme.txt。

更改「emailMessage.visible = YES;」到「emailMessage.visible = NO;」所以它在後臺發送它。

缺點:用戶需要在郵件下擁有有效的帳號。

解決方案3(Python腳本(無用戶帳戶): 您還可以使用python腳本發送消息。 缺點:用戶必須輸入SMTP的詳細信息,除非您從郵件中抓取郵件(但您可以直接使用上面的解決方案1),或者您必須在應用中使用硬編碼的可靠SMTP中繼(您可以設置Gmail帳戶並使用它用於這一目的,但如果您的應用程序發送過多的電子郵件,谷歌可以刪除自己的帳戶(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 = @"[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; 
     } 
    } 

我希望它有幫助

+1

腳本橋...如果我使用Thunderbird?還是Outlook?或者是其他東西? – 2011-04-04 06:24:53

+0

然後你可以使用perl腳本。郵件是最流行的電子郵件客戶端,如果它不存在,您可以使用請求用戶輸入他/她的SMTP詳細信息,或者您可以硬編碼您的郵件。 – Tibidabo 2011-04-04 06:36:28

+0

您的** Perl **腳本的第一行是#!/ usr/bin/env python ??? :-P – 2011-04-04 06:53:14

3

post應該幫助 - 它也引用example code

您還需要更改Controller.m或者線114在後臺發送消息:

emailMessage.visible = NO; 
+0

我已經看過那篇文章,但它打開了郵件應用程序,當你結束我不想要的電子郵件時,只想發送電子郵件,基本上我想製作我自己的郵件應用程序:),但感謝您的答案:D – 2011-03-28 16:05:14

26

這些反應是過時的Mac OS X 10.8,更應該使用NSSharingService

[啞劇
NSArray *[email protected][body,imageA,imageB]; 
NSSharingService *service = [NSSharingService sharingServiceNamed:NSSharingServiceNameComposeEmail]; 
service.delegate = self; 
[email protected][@"[email protected]"]; 
service.subject= [ NSString stringWithFormat:@"%@ %@",NSLocalizedString(@"SLYRunner console",nil),currentDate]; 
[service performWithItems:shareItems]; 

The sharing service documentation page

+1

這應該是被接受的答案。請注意,如果用戶使用Outlook,附件將不會被附加。 – fzwo 2014-08-06 09:52:38

+0

NSSharingService的另一個問題是,您無法事先設置作曲家的電子郵件正文(如果您需要這樣做)。 – 2014-08-21 08:08:17

+3

@ZS這是不正確的。請參閱performWithItems:設置消息正文。 – insys 2014-10-14 09:10:53