Вскрытие Почты.приложение из внешнего приложения с вложением и темой
Я хотел бы открыть почту.приложение и укажите тему и файл для прикрепления. Я могу сделать и то и другое независимо, но не то и другое.
Чтобы задать тему, я могу просто сформировать mailto: string и nsworkspace openURL.
Для установки приложения я могу использовать
[[NSWorkspace sharedWorkspace] openFile:resolvedPath withApplication:@"Mail"];
Я не знаю эквивалента MFMailComposeViewController iOS для Mac. Какие у меня варианты?
3 ответа:
Изменить: исходный код, на который он ссылается, был удален, поэтому я скопировал некоторые из них в этот ответ.
Вы можете использовать AppleScript (или Apple Events) для управления почтой.апп. Это имеет то преимущество, что нет ограничений на размер вложений, которые вы можете передавать, и позволяет избежать создания огромных 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:
создасти отправит электронное письмо одним ударом.
NSString* subject = @"mail subject"; NSString* body = @"mail body"; NSString* to = @"recipient@example.org"; NSString *encodedSubject = [NSString stringWithFormat:@"SUBJECT=%@", [subject stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; NSString *encodedBody = [NSString stringWithFormat:@"BODY=%@", [body stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; NSString *encodedTo = [to stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; NSString *encodedURLString = [NSString stringWithFormat:@"mailto:%@?%@&%@", encodedTo, encodedSubject, encodedBody]; NSURL *mailtoURL = [NSURL URLWithString:encodedURLString]; [[NSWorkspace sharedWorkspace] openURL:mailtoURL];
Это можно сделать довольно легко с помощью AppleScript, "интересная" часть заключается в том, как вызвать AppleScript из вашего приложения. Этот док должен дать вам то, что вам нужно: http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ScriptingBridgeConcepts/Introduction/Introduction.html
Хорошая часть AppleScript заключается в том, что вы можете использовать редактор сценариев, чтобы узнать, как вы хотите управлять внешним приложением, а затем закодировать его в приложении, как только это будет сделано.