Редактировать: Оригинальный код, ссылка на который была удалена, поэтому я скопировал часть этого ответа.
Вы можете использовать AppleScript (или Apple Events) для управления Mail.app. Это имеет то преимущество, что нет ограничений на размер вложений, которые вы можете пройти, и избегает построения огромных URL-адресов.
В нашем программном обеспечении, мы используем следующие скомпилировать подходящий AppleScript:
- (NSAppleScript *)script
{
if (script)
return script;
NSDictionary *errorInfo = nil;
/* This AppleScript code is here to communicate with Mail.app */
NSString *ourScript =
@"on build_message(sendr, recip, subj, ccrec, bccrec, msgbody,"
@" attachfiles)\n"
@" tell application \"Mail\"\n"
@" set mailversion to version as string\n"
@" set msg to make new outgoing message at beginning of"
@" outgoing messages\n"
@" tell msg\n"
@" set the subject to subj\n"
@" set the content to msgbody\n"
@" if (sendr is not equal to \"\") then\n"
@" set sender to sendr\n"
@" end if\n"
@" repeat with rec in recip\n"
@" make new to recipient at end of to recipients with properties {"
@" name: |name| of rec, address: |address| of rec }\n"
@" end repeat\n"
@" repeat with rec in ccrec\n"
@" make new to recipient at end of cc recipients with properties {"
@" name: |name| of rec, address: |address| of rec }\n"
@" end repeat\n"
@" repeat with rec in bccrec\n"
@" make new to recipient at end of bcc recipients with properties {"
@" name: |name| of rec, address: |address| of rec }\n"
@" end repeat\n"
@" tell content\n"
@" repeat with attch in attachfiles\n"
@" make new attachment with properties { file name: attch } at "
@" after the last paragraph\n"
@" end repeat\n"
@" end tell\n"
@" end tell\n"
@" return msg\n"
@" end tell\n"
@"end build_message\n"
@"\n"
@"on deliver_message(sendr, recip, subj, ccrec, bccrec, msgbody,"
@" attachfiles)\n"
@" set msg to build_message(sendr, recip, subj, ccrec, bccrec, msgbody,"
@" attachfiles)\n"
@" tell application \"Mail\"\n"
@" send msg\n"
@" end tell\n"
@"end deliver_message\n"
@"\n"
@"on construct_message(sendr, recip, subj, ccrec, bccrec, msgbody,"
@" attachfiles)\n"
@" set msg to build_message(sendr, recip, subj, ccrec, bccrec, msgbody,"
@" attachfiles)\n"
@" tell application \"Mail\"\n"
@" tell msg\n"
@" set visible to true\n"
@" activate\n"
@" end tell\n"
@" end tell\n"
@"end construct_message\n";
script = [[NSAppleScript alloc] initWithSource:ourScript];
if (![script compileAndReturnError:&errorInfo]) {
NSLog (@"Unable to compile script: %@", errorInfo);
[script release];
script = nil;
}
return script;
}
, то вы можете вызвать функции в сценарии с помощью кода, как этот
- (NSAppleEventDescriptor *)descriptorForThisProcess
{
ProcessSerialNumber thePSN = { 0, kCurrentProcess };
return [NSAppleEventDescriptor descriptorWithDescriptorType:typeProcessSerialNumber
bytes:&thePSN
length:sizeof (thePSN)];
}
- (BOOL)doHandler:(NSString *)handler
forMessage:(NSAttributedString *)messageBody
headers:(NSDictionary *)messageHeaders
{
NSMutableString *body = [NSMutableString string];
NSDictionary *errorInfo = nil;
NSAppleEventDescriptor *target = [self descriptorForThisProcess];
NSAppleEventDescriptor *event
= [NSAppleEventDescriptor appleEventWithEventClass:'ascr'
eventID:kASSubroutineEvent
targetDescriptor:target
returnID:kAutoGenerateReturnID
transactionID:kAnyTransactionID];
NSAppleEventDescriptor *params = [NSAppleEventDescriptor listDescriptor];
NSAppleEventDescriptor *files = [NSAppleEventDescriptor listDescriptor];
NSString *tmpdir = NSTemporaryDirectory();
NSString *attachtmp = nil;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *sendr = @"", *subj = @"";
NSAppleEventDescriptor *recip
= [self recipientListFromString:[messageHeaders objectForKey:@"To"]];
NSAppleEventDescriptor *ccrec
= [self recipientListFromString:[messageHeaders objectForKey:@"Cc"]];
NSAppleEventDescriptor *bccrec
= [self recipientListFromString:[messageHeaders objectForKey:@"Bcc"]];
unsigned numFiles = 0;
NSUInteger length = [messageBody length];
NSUInteger pos = 0;
NSRange range;
if ([messageHeaders objectForKey:@"Subject"])
subj = [messageHeaders objectForKey:@"Subject"];
if ([messageHeaders objectForKey:@"Sender"])
sendr = [messageHeaders objectForKey:@"Sender"];
/* Find all the attachments and replace them with placeholder text */
while (pos < length) {
NSDictionary *attributes = [messageBody attributesAtIndex:pos
effectiveRange:&range];
NSTextAttachment *attachment
= [attributes objectForKey:NSAttachmentAttributeName];
if (attachment && !attachtmp) {
/* Create a temporary directory to hold the attachments (we have to do this
because we can't get the full path from the NSFileWrapper) */
do {
attachtmp = [tmpdir stringByAppendingPathComponent:
[NSString stringWithFormat:@"csmail-%08lx",
random()]];
} while (![fileManager createDirectoryAtPath:attachtmp
withIntermediateDirectories:NO
attributes:nil
error:NULL]);
}
if (attachment) {
NSFileWrapper *fileWrapper = [attachment fileWrapper];
NSString *filename = [attachtmp stringByAppendingPathComponent:
[fileWrapper preferredFilename]];
NSURL *url = [NSURL fileURLWithPath:filename isDirectory:NO];
[fileWrapper writeToURL:url
options:NSFileWrapperWritingAtomic
originalContentsURL:nil
error:NULL];
[body appendFormat:@"<%@>\n", [fileWrapper preferredFilename]];
[files insertDescriptor:
[NSAppleEventDescriptor descriptorWithString:filename]
atIndex:++numFiles];
pos = range.location + range.length;
continue;
}
[body appendString:[[messageBody string] substringWithRange:range]];
pos = range.location + range.length;
}
/* Replace any CF/LF pairs with just LF; also replace CRs with LFs */
[body replaceOccurrencesOfString:@"\r\n" withString:@"\n"
options:NSLiteralSearch range:NSMakeRange (0, [body length])];
[body replaceOccurrencesOfString:@"\r" withString:@"\n"
options:NSLiteralSearch range:NSMakeRange (0, [body length])];
[event setParamDescriptor:
[NSAppleEventDescriptor descriptorWithString:handler]
forKeyword:keyASSubroutineName];
[params insertDescriptor:
[NSAppleEventDescriptor descriptorWithString:sendr]
atIndex:1];
[params insertDescriptor:recip atIndex:2];
[params insertDescriptor:
[NSAppleEventDescriptor descriptorWithString:subj]
atIndex:3];
[params insertDescriptor:ccrec atIndex:4];
[params insertDescriptor:bccrec atIndex:5];
[params insertDescriptor:
[NSAppleEventDescriptor descriptorWithString:body]
atIndex:6];
[params insertDescriptor:files atIndex:7];
[event setParamDescriptor:params forKeyword:keyDirectObject];
if (![[self script] executeAppleEvent:event error:&errorInfo]) {
NSLog (@"Unable to communicate with Mail.app. Error was %@.\n",
errorInfo);
return NO;
}
return YES;
}
- (BOOL)deliverMessage:(NSAttributedString *)messageBody
headers:(NSDictionary *)messageHeaders
{
return [self doHandler:@"deliver_message"
forMessage:messageBody
headers:messageHeaders];
}
- (BOOL)constructMessage:(NSAttributedString *)messageBody
headers:(NSDictionary *)messageHeaders
{
return [self doHandler:@"construct_message"
forMessage:messageBody
headers:messageHeaders];
}
Метод -constructMessage:headers:
, выше , заставит Mail открыть новое электронное письмо со всем уже заполненным, а метод -deliverMessage:headers:
создаст и отправит электронное письмо одним ударом.
-1 Не прикрепляет файл. –