Как добавить UIImage в лист MailComposer MFMailComposeViewController - PullRequest
53 голосов
/ 06 октября 2009

Я хочу вставить UIImage s внутри листа компоновки MFMailComposerViewController.

Обратите внимание, что я не хочу прикреплять их, но я хочу поместить их в таблицу, используя HTML-код, который будет частью тела письма.

Ответы [ 8 ]

64 голосов
/ 17 марта 2010

Снова с новым ответом. Я все еще оставляю свой предыдущий код, потому что я все еще не убежден, что нет способа использовать его. Я буду держать это на себе. Следующий код работает. Мустафа предлагает кодировать изображения в base64 и говорит, что они работают только от Apple до Apple, но на самом деле это не так. Кодировка Base64 теперь работает с большинством почтовых клиентов (ранее IE ее не поддерживал, но теперь она поддерживается для изображений до определенного размера, хотя я точно не знаю, какой это размер). Проблема в том, что почтовые клиенты, такие как Gmail, удаляют ваши изображения, но для этого есть простой обходной путь ... просто поместив теги <b> and </b> вокруг тега <img ...>, это все, что вам нужно сделать, чтобы предотвратить его удаление. , Чтобы вставить изображение в свою электронную почту, вам нужно добавить кодировщик base64 в ваш проект. Там есть несколько (в основном C), но самый простой ObjC, который я нашел, был назван NSData + Base64 Мэттом Галлахером (я вычеркнул "+" из названия после его копирования, потому что это дало мне проблемы). Скопируйте файлы .h и .m в свой проект и обязательно импортируйте файл .h туда, где вы планируете его использовать. Тогда код, подобный этому, вставит изображение в ваше тело письма ...

- (void)createEmail {
//Create a string with HTML formatting for the email body
    NSMutableString *emailBody = [[[NSMutableString alloc] initWithString:@"<html><body>"] retain];
 //Add some text to it however you want
    [emailBody appendString:@"<p>Some email body text can go here</p>"];
 //Pick an image to insert
 //This example would come from the main bundle, but your source can be elsewhere
    UIImage *emailImage = [UIImage imageNamed:@"myImageName.png"];
 //Convert the image into data
    NSData *imageData = [NSData dataWithData:UIImagePNGRepresentation(emailImage)];
 //Create a base64 string representation of the data using NSData+Base64
    NSString *base64String = [imageData base64EncodedString];
 //Add the encoded string to the emailBody string
 //Don't forget the "<b>" tags are required, the "<p>" tags are optional
    [emailBody appendString:[NSString stringWithFormat:@"<p><b><img src='data:image/png;base64,%@'></b></p>",base64String]];
 //You could repeat here with more text or images, otherwise
 //close the HTML formatting
    [emailBody appendString:@"</body></html>"];
    NSLog(@"%@",emailBody);

 //Create the mail composer window
    MFMailComposeViewController *emailDialog = [[MFMailComposeViewController alloc] init];
    emailDialog.mailComposeDelegate = self;
    [emailDialog setSubject:@"My Inline Image Document"];
    [emailDialog setMessageBody:emailBody isHTML:YES];

    [self presentModalViewController:emailDialog animated:YES];
    [emailDialog release];
    [emailBody release];
}

Я проверил это на iPhone и отправил мне замечательные электронные письма со встроенными изображениями на Yahoo, на моем личном веб-сайте и в MobileMe. У меня нет учетной записи Gmail, но Yahoo работал отлично, и каждый найденный мной источник говорит, что жирные метки - это все, что вам нужно, чтобы это работало. Надеюсь, это поможет всем!

11 голосов
/ 07 октября 2009

Есть два способа сделать это, в зависимости от того, где хранятся изображения:

Если изображения отсутствуют на сервере, просто включите теги HTML <img> с исходным URL-адресом, установленным для удаленного изображения. При предварительном просмотре почтового сообщения пользователю показывается изображение во время композиции, а получатель видит его, когда открывает сообщение (если только он не отключил загрузку изображения по умолчанию).

Если изображения находятся на телефоне, вы можете включить их в виде «встроенных» изображений. Есть два шага к этому. Сначала вы должны прикрепить все изображения, которые вы хотите использовать в качестве многокомпонентных вложений MIME, и им нужно будет назначить «идентификатор контента» (он же cid), имя файла и Content-Disposition, установленный на inline. Внутри вашего HTML-сообщения вы можете ссылаться на них так:

<img src="cid:{messageid}/image.png" alt="My image" />

Плохая новость заключается в том, что стандартный механизм компоновки почты iPhone не позволяет добавлять эти дополнительные данные во вложения. Второе - пометить электронное письмо как «альтернативный» тип содержимого MIME. Опять же, почтовый композитор не позволяет вам сделать это.

Способ обойти это - либо составить сообщение самостоятельно, а затем отправить его на почтовый сервер напрямую через SMTP, либо попросить прокси-сервер сделать это за вас через ретранслятор SMTP. Если вы решите пойти по этому пути, вы можете проверить skpsmtpmessage в коде Google или в сервисе, подобном AuthSMTP .

Однако, как только пользователь получает это сообщение, он видит отдельное HTML-сообщение со всеми встроенными изображениями прямо здесь. Но это очень сложно настроить. Первый способ (размещение изображений на сервере) - гораздо более простой способ.

4 голосов
/ 15 марта 2011

Для iOS 3.0 и более поздних версий, пожалуйста, смотрите это: Прикрепить изображение к электронному письму?

Пример:

UIImage * image = [UIImage imageWithContentsOfFile:imagePath];
[composer addAttachmentData:UIImageJPEGRepresentation(itemImage, 1) mimeType:@"image/jpeg" fileName:@"MyFile.jpeg"];
1 голос
/ 10 марта 2010

(К сожалению, следующий метод не работает, но я оставляю этот пост, потому что пример строки преобразования пути URL-адреса изображения действительно полезен для других случаев, когда вам нужны HTML-пути к файлам в вашем коде. Пожалуйста, смотрите мой пост на Base64Encoding для способа, который работает.)

Я сам столкнулся с этой проблемой и нашел способ, который работает. Вы МОЖЕТЕ заставить изображения появляться встроенными, используя полный путь к файлу изображения.

Это займет небольшое преобразование с вашей стороны, но используйте обычные методы для получения каталогов вашего приложения (NSString *path = [[NSBundle mainBundle] resourcePath], etc...), затем преобразуйте строку в буквальный URL. Например, возвращаемая выше строка «path» будет содержать что-то вроде »/ Users / Me / Библиотека / Поддержка приложений / iPhone Simulator / 3.2 / Applications / 25ADA98D-8DF4-4344-8B78-C18BC757EBDC / MyEmailingApplication.app" .

Вам нужно будет превратить эту строку в

" file: /// Пользователи // Me // Библиотека // Приложение% 20Support // iPhone% 20 Simulator // 3.2 // Приложения // 25ADA98D-8DF4-4344-8B78-C18BC757EBDC // MyEmailingApplication .app // "

и затем вы можете добавить имена файлов изображений до конца. (этот пример указывает на ресурсы приложения, но то же самое относится к каталогам tmp и documents).

Вы можете выполнить преобразование этой строки с помощью комбинации [NSString stringWithFormat:@"file:///%@//%@",path,myImageName]

после использования [path stringByReplacingOccurencesOfString:@"/" withString:@"//"]

для исправления косой черты в «пути» и

[path stringByReplacingOccurencesOfString:@" " withString:@"%20"]

чтобы сделать пробелы удобными для HTML. Теперь вы можете использовать этот буквальный URL в своем теле письма в формате HTML, например, img src = \ "", pathToMyImage, "\"

Пример выглядит как большая работа, но на самом деле, как только вы его настроите, это совсем не сложно, и он работает как шарм :-) Удачи!

1 голос
/ 18 января 2010

Может быть, это сработает для вас:

Как встроить UIImage в тело сообщения Mail Composer

Вот что он говорит:

По сути, вы конвертируете свое изображение в строку base64 (прикрепленная ниже base64 должна быть сокращена из-за ограничения длины сообщения, чтобы оно не было допустимым изображением) и вставлялась в тег image. Я помню, что я перестал работать над этим, потому что встроенные изображения можно просматривать только с iPhone на другой iPhone, я помню, как тестировал их с Gmail, наш рабочий клиент Outlook без везения отображал изображение, когда я просматривал исходные данные есть. Так что я не думаю, что это проблема спам-фильтра, но почтовые клиенты просто умнее. Пока я изучал этот вопрос, я обнаружил, что именно столько спамеров рассылают электронные письма с информацией только для изображений, чтобы она пропускала спам-фильтр. Черт побери, я собирался использовать его по уважительной причине, но, поскольку я обнаружил, что большинство почтовых клиентов не будет отображать изображение, это было практически бесполезно. Для чего это стоит, вот код.

NSString *eMailBody = @"<html>Just convert your image file to base64 to embed into the email<img src="data:image/gif;base64,R0lGODlhFAFuAPcAAPf39//7/+fn59bT1u/r787Lzq0UAN7b3hhFrRhJtRA0hBA8lMYYALWytffz94wQAMa+vb26vRhNxufj5+/v78bDxvfz772+vcbHxghRCM7PzggkYyFZ1tYkCNbX1hhRzpyenO+6AN7f3gBlANauAGOW7zFl1kp95wg8pbW2tZyanHOi797f5zlx3msMAAB9CP/PAL22va2mraWipedJMSlRtf91Y72WAFqK76WmpRBFta2qrcaeAK2urfdpUuc8If39/e9ZQmPTY94wGFrLWrUkEISq9/n5+ZR5ABCWGLWOAIRpAGNRAClJlK2GAL0sGGssITG2OaWCAK3H9848KaW+762qpcbX/73jvWN5pGvTc/eGc//vCFppfIwgEJRBMYSGlPeWhJSSjHN5jMaSjKWmrb3P787V1ilBa4R9c9nXy+rq6ntNQu/y95Su3svO1kphlISa1t7b1vf7/3uGraWGexdAmoySlDm6QrWyraWqrRiiIWtpa0LDStrl/1JtrcbHzpxlWntlUklVcztZk3vbhISStfffWufr786upVmB1ta2taW21tLS0ve6rd7j5zlhtfemnJSetefn78LCw7W2vdnZ2bVFMf/3//f3/8Z1a9bb59bb3eHh4a2WjM7HxoR1OSGqKbW6xvT09JyGQrXD3v/r5+fk3s7rzufb3q2ytffXKbWiY6inp1p1WrWmjP/LxnOOzsC/v+/n56qSMffXzr2eEP/3hPHx8f//987T57m4ubVZShk5f97LjO/HKQ03ks7DpdZlWv/vMd7LxqWuvefr/86uKd66QgwyhcnJyf/ztbKxsrWqpe/37//z7///75zTpf/397Szsvfn1ozLjO/jlN7v3qWko62OEO/r5//73tbX3vf37wotd1qqYxlNvYyujN7X1qKgoHuWe5KUmkKOQhZKvildMRh5IZqZmcXEwZ2amaajoNfU0QMaTAsiV5STlSo+bZibpSti2puZl5u28pGs5pqbn9Hd8/fr94WFi7i1sBguYfP09v///ywAAAAAFAFuAAAI/wD/CRxIsKDBgwgTKlzIsKHDhxAjSpxIsaLFixgzatzIsaPHjyBDihxJsqTJkyhTqlzJsqXLlzBjypxJs6bNmzhz6tzJs6fPn0CDCh1KtKjRo0iDYinEtJAWLUSIfJv6DVFShnOMXTEzpYrXKlPMXDGW6apZhli0CHmqtk+oJC9ejDDH6azBTGaMKDLBQUKCvzoC/5XAwcSJElV0UbB71lk0PFH6CGmqxS3cuZgyAwhw1tiUEiY+CEZBunTpwR9SfyisiNGmzYyNYqlWLZrtak6JRLmcoQKBCQQswEZ6ZcUJDn0RoFiwoAkhOH/+wCHURDkKHRIII0e+uoWbSbGRYv/SFy0qnj1yM6ArUEDDAQEOOBu9UqIF3xrMCWWRBGiAnP8eqKEBBpVIkgUhyg22nWocxKJLeEMBYIEAqVSD"></html>";

NSString *encodedBody = [eMailBody stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *urlString = [NSString stringWithFormat:@"mailto:someone@someplace.com?subject=ImageTest&body=%@", encodedBody];
NSURL *url = [[NSURL alloc] initWithString:urlString];
[[UIApplication sharedApplication] openURL:url];
0 голосов
/ 27 августа 2014

Я попробовал ответ Майка , который прекрасно работает внутри MFMailComposerViewController, но, к сожалению, не с большинством почтовых клиентов. Поскольку мне действительно нужно отправить содержимое электронной почты со встроенным UIImage , вот что я сделал:

  1. Я сохранил код ответа Майка , чтобы сгенерировать мою HTML-страницу с UIImage
  2. Я создал UIWebView, представляющий эту страницу, с [yourwebview loadHTMLString:@"yourHTMLString" baseURL:nil]
  3. ВАЖНО: я отображаю это в UIViewController как Страница предварительного просмотра для пользователя
  4. Затем я генерирую PDF из этого UIWebView, благодаря методу AnderCover
  5. Наконец, я добавляю созданный PDF-файл в качестве приложения к электронному письму с [mailComposerController addAttachmentData:yourPDFFileAsNSData mimeType:@"application/pdf" fileName:@"yourFileName.pdf"]

Хорошо, не вините меня, я знаю, что это много конверсий и действий для простого добавления некоторых изображений, но ваша HTML-структура электронной почты остается такой же со встроенными изображениями , и конечный пользователь будет получить только одно симпатичное вложение .
«Грязная» часть заключается в том, что содержимое PDF на самом деле представляет собой скриншоты веб-просмотра ... На самом деле его нельзя использовать повторно.

0 голосов
/ 15 марта 2011
  1. удалить тег изображения
  2. просто возьмите удаленный тег изображения и отобразите с помощью вида uimage

Я пробовал приведенные выше примеры, но они не работают. Ниже вы найдете пример кода, который работает на 100%. Но вам нужно проверить URL-адрес тега изображения.

//remove  the img tag 

NSScanner *theScanner;
NSString *gt =nil;

theScanner = [NSScanner scannerWithString:emailBody];

while ([theScanner isAtEnd] == NO) {

    // find start of tag
    [theScanner scanUpToString:@"<img" intoString:NULL] ; 

    // find end of tag
    [theScanner scanUpToString:@">" intoString:&gt] ;


    emailBody = [emailBody stringByReplacingOccurrencesOfString:[ NSString stringWithFormat:@"%@>", gt] withString:@""];
    NSString *tt=[ NSString stringWithFormat:@"%@>", gt];
        NSLog(@"*********************%@",tt);
    st=tt;
        NSLog(@"*********************%@",st);
}
st =[st stringByReplacingOccurrencesOfString:@"<img src=\"" withString:@""];
st =[st stringByReplacingOccurrencesOfString:@"\"/>" withString:@""];
st =[st stringByReplacingOccurrencesOfString:@".png" withString:@""];
st =[st stringByReplacingOccurrencesOfString:@"\"align=\"left" withString:@""];
//"align="left
NSLog(@"*********************%@",st);



NSString *path1 = [[NSBundle mainBundle] pathForResource:[ NSString stringWithFormat:@"%@", st] ofType:@"png"];
NSData *myData1 = [NSData dataWithContentsOfFile:path1];
[picker addAttachmentData:myData1 mimeType:@"image/png" fileName:[ NSString stringWithFormat:@"%@", st]];
0 голосов
/ 11 марта 2010

РЕДАКТИРОВАТЬ: То, что вы собираетесь читать, не работает (пока)! Проверьте мой другой пост на Base64 Кодирование вашего изображения, которое работает.

Это выглядит очень хорошо в окне составления электронной почты, но фактическое отправленное электронное письмо не включает фотографии (я только что проверил это на своем телефоне). Я ошибочно подумал, что почтовое приложение само кодирует base64-изображения (это относится и к прикрепленным изображениям). И хотя это неудобно, вы можете получить электронное письмо на iPhone, чтобы вставить несколько «поточных» встроенных изображений, перейдя в папку с изображениями, скопировав изображение в буфер обмена, перейдя по электронной почте и вставив его в нужное место. Вы можете написать больше текста, сохранить письмо как черновик и повторить процесс, добавив больше изображений в одно и то же письмо. Отправьте электронное письмо себе, затем откройте его на своем компьютере с помощью Text Edit. Вы сможете точно увидеть форматирование электронной почты (включая изображения в кодировке base64).

Что странно происходит с моим кодом ниже, так это то, что текст попадает в электронное письмо, но изображения просто полностью исчезают (даже не висящая «сломанная» ссылка на них: - /). Это заставляет меня сомневаться, что ссылки на изображения на внешнем сервере будут работать. Я собираюсь продолжить работу над этим ... Мне интересно, будет ли это вести себя иначе, если у меня будет запуск электронной почты в почтовом приложении вне моей программы. Я продолжу возвращаться, чтобы обновить это, поскольку я выясняю больше ... просто кажется, что это должно быть проще, чем Apple делает это: - /

Этот код написан для файлов изображений, которые вы будете хранить в своем каталоге «Documents» (поэтому ваше приложение должно будет создавать изображения, которые там хранятся, и HTML-код, который ссылается на эти изображения. Для изображений, которые вы сохранили в комплекте приложения используйте [[NSBundle mainBundle] resourcePath] для начального пути к изображениям).

- (void)createEmailWithInlineImages {
//get app Documents directory
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsPath = [paths objectAtIndex:0];
//make spaces HTML friendly
    documentsPath = [documentsPath stringByReplacingOccurrencesOfString:@" " withString:@"%20"];
//make forward-slash into double-forward-slash for HTML file-URL comapatibility
    documentsPath = [documentsPath stringByReplacingOccurrencesOfString:@"/" withString:@"//"];
//get the name for your image into the string however your app works
//create a string formatted like a literal HTML URL to the image, e.g.
//file:///myiPhoneFileSystemPath//MyApplication//MyApplicationDirectories//Documents//imageName.jpg
    NSString *myHTMLImageName = @"myHTMLImage.jpg";
    NSString *imagePath = [NSString stringWithFormat:@"file:///%@//%@",documentsPath,myHTMLImageName];

//this string is an example of your email body text with HTML formatting
    NSString *emailText = [NSString stringWithFormat:@"%@%@%@",@"<html><head><title>My Inline Image Example Email</title></head><body><p>Here's some text before the inline image</p><p><img src = \"",imagePath,@"\"></p><p>Here's some text for after the inline image. You could add more inline images and text after this with the same kind of formatting.</p></body></html>"];

//create email
    MFMailComposeViewController *emailDialog = [[MFMailComposeViewController alloc] init];
    emailDialog.mailComposeDelegate = self;
    [emailDialog setSubject:@"My Inline Image Email Document"];

    [emailDialog setMessageBody:emailText isHTML:YES];

    [self presentModalViewController:emailDialog animated:YES];
    [emailDialog release];
}
...