Как добавить UIImage в лист MailComposer MFMailComposeViewController

Я хочу вставить UIImages в составной лист MFMailComposerViewController.

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


person rkb    schedule 06.10.2009    source источник
comment
Вам случайно не повезло с этим в последнее время? Я работаю над той же проблемой и тоже сталкиваюсь с той же проблемой.   -  person jcrowson    schedule 28.03.2012
comment
см. stackoverflow.com/questions/12210571/   -  person msk    schedule 08.03.2014


Ответы (8)


Снова с новым ответом. Однако я все еще оставляю свой предыдущий код, потому что я все еще не уверен, что его нельзя использовать. Я буду продолжать в том же духе. Следующий код работает. Мустафа предлагает кодировать изображения с помощью 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 работал отлично, и каждый источник, который я нашел, говорит, что полужирные теги - это все, что вам нужно, чтобы заставить его работать. Надеюсь, это поможет всем!

person Mike    schedule 17.03.2010
comment
Вы недавно проверяли это с помощью gmail? Кажется, я получаю только кучу текста вместо изображения. - person Steven Baughman; 20.07.2010
comment
Трюк с ‹b›‹/b› больше не работает. Что бы я ни делал, Gmail не отображает изображение. Настольный клиент работает нормально. - person Ryan Booker; 17.09.2010
comment
[[[NSMutableString alloc] initWithString:@"<html><body>"] retain]: alloc уже удерживает, так что вы удерживаете слишком много - person user102008; 04.12.2010
comment
Вот только новости по этому вопросу. Этот подход НЕ работает для меня с Gmail, Yahoo или Hotmail. Встроенные изображения в кодировке base 64 не отображаются. Но Map.app показывает встроенные изображения (Mac и iOS), но этого недостаточно. - person Mustafa; 15.04.2011
comment
Это также неправильно отображается в Gmail на Android, Outlook или Zimbra. - person Heath Borders; 20.03.2012
comment
Подтверждено: очень хорошая и простая в реализации идея.. Но не работает с большинством известных серверов электронной почты.. Жаль :( - person Tib; 27.08.2014

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

Если изображения находятся на сервере, просто включите теги 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-сообщение со всеми встроенными изображениями. Но очень хлопотно с настройкой. Первый метод (размещение изображений на сервере) намного проще.

person Ramin    schedule 06.10.2009
comment
Таким образом, вы просто можете напрямую вставить UIImages, хранящиеся в базе данных iPhone. Вам нужно либо хранить их на сервере, либо создать сообщение самостоятельно и отправить его. - person rkb; 07.10.2009

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

Пример:

UIImage * image = [UIImage imageWithContentsOfFile:imagePath];
[composer addAttachmentData:UIImageJPEGRepresentation(itemImage, 1) mimeType:@"image/jpeg" fileName:@"MyFile.jpeg"];
person Arie Litovsky    schedule 15.03.2011

Возможно, это сработает для вас:

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

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

По сути, вы конвертируете свое изображение в строку base64 (прикрепленное ниже base64 должно быть сокращено из-за ограничения длины сообщения, поэтому это недопустимое изображение) и вставляете его в тег изображения. Я помню, что перестал работать над этим, потому что встроенные изображения можно просматривать только с 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:[email protected]?subject=ImageTest&body=%@", encodedBody];
NSURL *url = [[NSURL alloc] initWithString:urlString];
[[UIApplication sharedApplication] openURL:url];
person Mustafa    schedule 18.01.2010

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

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

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

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

"file:///Users//Me//Library//Application%20Support//iPhone%20 Simulator//3.2//Applications//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,"\".

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

person Mike    schedule 10.03.2010
comment
Дерьмо! Проверьте полный код, который я разместил ниже. Это не работает при фактической отправке с устройства. Это выглядит идеально в окне композиции (изображения, отображающие встроенные и все такое), но фактическое отправленное электронное письмо не включает изображения или внедряющий их код :-( Пока я оставляю это опубликованным, пока я проверяю его на случай, если это направляет нас на правильный путь. - person Mike; 11.03.2010
comment
Он работает в окне композиции, потому что вы напрямую ссылаетесь на расположение локального файла. Поэтому, когда вы отправляете его, ссылка остается прежней (на ваше локальное местоположение файла). Вот почему это не работает. Потому что файла больше нет. - person jyap; 04.06.2012

Я попробовал, что ответ Майка отлично работает внутри 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 остается прежней со встроенными изображениями, и конечный пользователь получит < strong>только одно красивое вложение.
Грязная часть заключается в том, что содержимое PDF на самом деле является снимком экрана веб-просмотра... На самом деле его нельзя использовать повторно.

person Tib    schedule 27.08.2014

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

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

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

Этот код написан для файлов изображений, которые вы храните в каталоге «Документы» (поэтому ваше приложение должно создавать изображения, хранящиеся там, и код HTML, который ссылается на эти изображения. Для изображений, которые вы сохранили в приложении bundle, используйте [[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];
}
person Mike    schedule 11.03.2010
comment
Кстати, спасибо Рамину за первоначальное упоминание о том, что изображения, хранящиеся на сервере, будут работать. Это натолкнуло меня на мысль попробовать буквальные URL-адреса в файловой системе iPhone :-) - person Mike; 11.03.2010
comment
Если вы не видели мою заметку выше, посмотрите мой новый пост RE:Base64Encoding your image. Это работает очень хорошо для большинства случаев. - person Mike; 17.03.2010

  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]];
person pratap shaik    schedule 15.03.2011