How can I send a HTML email from Cocoa?

后端 未结 3 1179
粉色の甜心
粉色の甜心 2020-12-10 17:31

I\'m looking for a way to create a HTML formatted email from a OS X Cocoa application.

My preferred workflow would be: The user selects a menu item and the default m

相关标签:
3条回答
  • 2020-12-10 17:53

    I was interested in this too, so two days of reverse engineering Safaris 'Mail Contents of This Page' feature 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 doesn't check if Mail is running, so it's only working when Mail is already started.

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

    The downside is that you can't set recipients like with a mailto. For this the Scripting Bridge seems the only solution. See this modified SBSendEmail sample.

    0 讨论(0)
  • 2020-12-10 18:00

    There's no standard way to do complex interactions with arbitrary email clients. You would have to tackle each application you want to support separately, and see if it has a way to set the email format--most likely via Applescript--and then detect what the default mailto handler is and run the appropriate code. For some email clients, it may not be possible (just as some clients have no supported way to open a new email with an attachment).

    0 讨论(0)
  • 2020-12-10 18:01

    Dustin Bachrach posted an elegant (but incomplete) solution here

    It needs a bit of apple script, so you would have to create a different script for each mail app you want to support, but it seems like an easy thing to do.

    You would also need to find the users default mail app which can be done by constructing a mailto: url then use LaunchServices LSGetApplicationForURL(): to return the default email client.

    0 讨论(0)
提交回复
热议问题