Отправить письмо от Какао - PullRequest
14 голосов
/ 28 марта 2011

Как я могу отправить электронное письмо из приложения Какао без использования почтовых клиентов?У меня есть NSURL, но он открывает почтовый клиент.Я хотел бы отправить электронное письмо без этого.

Ответы [ 4 ]

29 голосов
/ 19 февраля 2014

Эти ответы устарели для 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];

Страница документации службы обмена

25 голосов
/ 04 апреля 2011

ОБНОВЛЕНИЕ: Как другие предложили, из 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: *. 1013 *- (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):

вложения - это массив строк, содержащих пути к файлам

- (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, чтобы использовать Mail для отправки вашего сообщения
Превосходная ссылка Apple Это довольно просто, вам нужно только возиться с добавлением правила и Mail.app в ваш проект.Внимательно прочитайте файл Readme.txt.

Измените "emailMessage.visible = YES;"to "emailMessage.visible = NO;"поэтому он отправляет его в фоновом режиме.

Недостаток: пользователям необходимо иметь действительные учетные записи в Mail.

Решение 3 (Python Script (без учетной записи пользователя): Вы также можете использовать сценарий python дляотправьте сообщение. Недостаток: пользователи должны вводить данные SMTP, если вы не получаете их из Почты (но затем вы можете напрямую использовать Решение 1, описанное выше), или вам не нужно иметь надежное реле 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;
        }
    }

Надеюсь, это поможет

3 голосов
/ 28 марта 2011

Этот пост должен помочь - он цитирует пример кода тоже.

Вам также необходимо изменить строку 114 в Controller.m, чтобы отправить сообщение в фоновом режиме:

emailMessage.visible = NO;
0 голосов
/ 28 марта 2011

Вам нужно будет использовать Простой протокол пересылки почты (SMTP). Эта ссылка даст вам простой обзор того, как это работает: Понимание протокола SMTP .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...