2011-03-28 25 views
12

¿Cómo puedo enviar un correo electrónico desde una aplicación Cocoa sin utilizar ningún cliente de correo electrónico? Tengo NSURL pero abre un cliente de correo electrónico. Me gustaría enviar el correo electrónico sin que esto ocurra.Enviar correo electrónico desde Cocoa

+0

posible duplicado de [Pantomima = obsoleta. Enviando y recibiendo el marco de correo] (http://stackoverflow.com/questions/3567251/pantomime-outdated-sending-and-receiving-mail-framework) –

+0

posible duplicado de [Enviar correo electrónico - Cocoa] (http: // stackoverflow. com/questions/1396229/send-email-cocoa) –

Respuesta

24

ACTUALIZACIÓN: Como otros sugirieron, desde 10,9 puede utilizar NSSharingService que soporta archivos adjuntos, así!

ejemplo Swift:

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 

    } 

ACTUALIZACIÓN VIEJO:. Mis viejos respuestas funcionado bien hasta que tuve que sandbox mis aplicaciones de la App Store ~~ Desde entonces la única solución que encontré estaba usando simplemente un mailto: enlace.

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

Desventaja: No attachment! Si sabes cómo hacer que funcione en Mac, ¡házmelo saber!

vieja respuesta: Usted puede Manzana Script, estructura de puente de secuencias de comandos de Apple (Solución 2) o una secuencia de comandos de Python (Solución 3)

Solución 1 (secuencia de comandos de Apple):

adjuntos es una matriz de picaduras que contienen las rutas de archivos

- (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 ción 2 (Apple scriptingbridge framework): Puede usar el marco scriptingbridge de Apple para usar Mail para enviar su mensaje
Apple's exmaple link, es bastante sencillo, solo tiene que jugar con agregar una regla y Mail.app a su proyecto. Lee Readme.txt con cuidado.

Cambiar "emailMessage.visible = YES;" a "emailMessage.visible = NO;" por lo que lo envía en segundo plano.

Desventaja: los usuarios deben tener cuentas válidas en Correo.

Solución 3 (Python Script (sin cuenta de usuario): También puede usar un script de python para enviar un mensaje. Desventaja: los usuarios deben ingresar detalles de SMTP a menos que los agarre de Mail (pero luego puede usar directamente la Solución 1 anterior), o tiene que tener un reenvío de SMTP confiable codificado en su aplicación (puede configurar una cuenta de gmail y usar para ese propósito, sin embargo, si sus aplicaciones envían demasiados mensajes de correo electrónico de Google pueden eliminar su cuenta (SPAM))
yo uso este script en 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() 

Y me llaman formar este método para enviar un correo electrónico utilizando una Cuenta de 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; 
     } 
    } 

Espero que ayude

+1

Scripting Bridge ... ¿Qué pasa si uso Thunderbird? ¿O Outlook? ¿O algo mas? –

+0

Luego puede usar el script Perl. El correo es el cliente de correo electrónico más popular; si no está presente, puede solicitarle al usuario que ingrese sus datos de SMTP o puede codificar el suyo. – Tibidabo

+0

La primera línea de su script ** Perl ** es #!/Usr/bin/env python ??? :-P –

3

Este post debería ayudar; también cita example code.

También es necesario cambiar la línea 114 en Controller.m para enviar el mensaje de fondo:

emailMessage.visible = NO; 
+0

He echado un vistazo a esa publicación antes, pero abre la aplicación de correo cuando terminas el correo electrónico que realmente no quiero, solo quiero enviar el correo electrónico, básicamente Quiero hacer mi propia aplicación de correo :), pero gracias por la respuesta: D –

26

Aquellos respuesta son obsoletas Mac OS X 10.8 y más se debe utilizar 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

Esta debería ser la respuesta aceptada. Tenga en cuenta que si el usuario usa Outlook, los archivos adjuntos no se adjuntarán. – fzwo

+0

Otro problema con NSSharingService es que no puede establecer el cuerpo del correo electrónico del compositor de antemano (si es algo que debe hacer). –

+3

@ZS esto no es correcto. Consulte performWithItems: para establecer el cuerpo del mensaje. – insys

Cuestiones relacionadas