How can I send an HTML email from Cocoa?

I am looking for a way to create HTML formatted email from an OS X Cocoa application.

My preferred workflow: The user selects a menu item, and by default the mail application opens with a pre-filled new message in the foreground.

I can do this using mailto and - [NSWorkspace openURL] for text email messages, but this does not work for HTML emails.

+6
email cocoa macos
source share
3 answers

I was also interested in this, so two days of reverse engineering Safaris "Mail Contents of this Page", and I got it working.

UPDATE: I improved the code and put it on GitHub

- (void)mailWebArchive:(WebArchive *)webArchive title:(NSString *)aTitle URL:(NSString *)aURL { NSString *bundleID = @"com.apple.mail"; NSData* targetBundleID = [bundleID dataUsingEncoding:NSUTF8StringEncoding]; NSAppleEventDescriptor *targetDescriptor = nil; NSAppleEventDescriptor *appleEvent = nil; targetDescriptor = [NSAppleEventDescriptor descriptorWithDescriptorType:typeApplicationBundleID data:targetBundleID]; appleEvent = [NSAppleEventDescriptor appleEventWithEventClass:'mail' eventID:'mlpg' targetDescriptor:targetDescriptor returnID:kAutoGenerateReturnID transactionID:kAnyTransactionID]; [appleEvent setParamDescriptor:[NSAppleEventDescriptor descriptorWithDescriptorType:'tdta' data:[webArchive data]] forKeyword:'----']; [appleEvent setParamDescriptor:[NSAppleEventDescriptor descriptorWithString:aTitle] forKeyword:'urln']; [appleEvent setParamDescriptor:[NSAppleEventDescriptor descriptorWithString:aURL] forKeyword:'url ']; NSAppleEventDescriptor *replyDescriptor = nil; NSAppleEventDescriptor *errorDescriptor = nil; AEDesc reply = { typeNull, NULL }; // Send the AppleEvent OSStatus status = AESendMessage([appleEvent aeDesc], &reply, kAEWaitReply, kAEDefaultTimeout); if(status == noErr) { replyDescriptor = [[[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&reply] autorelease]; errorDescriptor = [replyDescriptor paramDescriptorForKeyword:keyErrorNumber]; if(errorDescriptor != nil) status = [errorDescriptor int32Value]; if(status != noErr) NSLog(@"%s error %d", _cmd, status); } } 

This code does not check if Mail works, so it only works when Mail starts.

The pro side of this approach is that it works with all email clients that implement MailLinkSupported and MailPageSupported. See QA1722 .

The disadvantage is that you cannot set recipients, for example, using mailto . For this, the Scripting Bridge seems to be the only solution. See This Modified SBSendEmail Sample .

+10
source share

There is no standard way to perform complex interactions with arbitrary email clients. You will need to solve each application that you want to support separately, and see if it has a way to set the email format - most likely through Applescript - and then determine what is the default mail handler and run the appropriate code. For some mail clients this may not be possible (just as some clients do not support the way to open a new letter with the application).

+3
source share

Dustin Bachrach posted an elegant (but incomplete) solution here

It needs a little apple script, so you need to create a different script for each mail application you want to support, but this seems like an easy thing.

You will also need to find the default email application for users, which can be done by creating the mailto: URL, and then use LaunchServices LSGetApplicationForURL(): to return the default email client.

0
source share

All Articles