2009-07-16 45 views
6

Tôi đang tìm cách tạo email được định dạng HTML từ ứng dụng OS X Cocoa.Tôi làm cách nào để gửi email HTML từ Cocoa?

Luồng công việc ưa thích của tôi sẽ là: Người dùng chọn mục menu và ứng dụng thư mặc định sẽ mở ra bằng email mới được điền sẵn ở nền trước.

Tôi có thể thực hiện việc này với mailto và - [NSWorkspace openURL] cho email văn bản thuần tuý, nhưng điều này không hoạt động đối với email HTML.

+0

Một vài tài nguyên: http://cocoaheads.byu.edu/resources/email –

+0

Bất kỳ tin tức nào về vấn đề này? –

Trả lời

10

Tôi cũng quan tâm đến điều này, vì vậy, hai ngày kỹ thuật đảo ngược nội dung thư của Safaris 'Nội dung của trang này' và tôi nhận được nó hoạt động.

UPDATE: tôi cải thiện mã và đặt nó trên 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); 
} 
} 

Mã này không kiểm tra xem Thư đang chạy, vì vậy nó chỉ làm việc khi Thư đã được bắt đầu.

Mặt chuyên nghiệp của phương pháp này hoạt động với tất cả ứng dụng email thực hiện MailLinkSupported và MailPageSupported. Xem QA1722.

Nhược điểm là bạn không thể đặt người nhận như với mailto. Đối với điều này, Scripting Bridge có vẻ là giải pháp duy nhất. Xem sửa đổi này SBSendEmail sample.

+0

Cảm ơn Chris. Điều gì đi vào baseURL trong phương thức ATMailHelper? – lostInTransit

+0

Tệp được sử dụng để giải quyết các URL tương đối trong tài liệu. Bạn cần điều này trong trường hợp thư html của bạn dưới dạng hình ảnh không được tải xuống từ web. – catlan

+0

Tôi không có bất kỳ hình ảnh nào. Tôi phải làm gì sau đó? Nhận thấy rằng không có baseURL, WebResource không được tạo ra – lostInTransit

3

Không có cách nào tiêu chuẩn để thực hiện các tương tác phức tạp với các ứng dụng email tùy ý. Bạn sẽ phải giải quyết từng ứng dụng mà bạn muốn hỗ trợ riêng và xem liệu nó có cách thiết lập định dạng email - rất có thể thông qua Applescript - và sau đó phát hiện trình xử lý mailto mặc định là gì và chạy mã thích hợp. Đối với một số ứng dụng email, có thể không thực hiện được (giống như một số khách hàng không có cách nào được hỗ trợ để mở một email mới có tệp đính kèm).

+0

Tôi khá nhiều đến cùng một kết luận sau khi thực hiện tìm kiếm mở rộng trên Internet. Tôi hiện đang thử một giải pháp Mail.app chỉ thông qua Scripting Bridge, nhưng cho đến nay tôi không thành công thiết lập một văn bản phong phú/html như nội dung thư. Nếu tôi tìm được giải pháp, tôi sẽ thêm nó vào câu hỏi này. –

0

Dustin Bachrach đăng một giải pháp thanh lịch (nhưng không đầy đủ) here

Nó cần một chút kịch bản táo, vì vậy bạn sẽ phải tạo ra một kịch bản khác nhau cho mỗi ứng dụng mail bạn muốn hỗ trợ, nhưng nó có vẻ như một điều dễ làm.

Bạn cũng cần phải tìm ứng dụng thư mặc định của người dùng có thể được thực hiện bằng cách tạo địa chỉ mailto: sau đó sử dụng LaunchServices LSGetApplicationForURL(): để trả lại ứng dụng email mặc định.

Các vấn đề liên quan