ПРОГРАММИРОВАНИЕ ПОД IPHONE, IPAD OBJECTIVE-C Часть 1

Отправка Email с приложения

Возможность отправлять письма с приложения добавляет ему несколько полезных возможностей. Первое — это самореклама самого приложения. К примеру вы пишете игру. И добавляете возможность отправить количество полученых очков другу игрока. Есть шанс, что друг захочет тоже попробовать свои силы и так дальше. Вторая, не менее важная функция — это возможность отправки данных с приложения (в виде прикрепленных к письму файлов). И наконец, банальная отправка теста.

 

Но перейдем от теории к практике, создадим приложение на основе шаблона Single View Application и назовем его MailSender. Первое, что нам нужно сделать — это добавить фреймверк MessageUI.framework и импортировать его в интерфейс класса ViewController:

 

ViewController.h

<code data-result="[object Object]">#import &lt;UIKit/UIKit.h&gt;
#import &lt;MessageUI/MessageUI.h&gt;
#import &lt;MessageUI/MFMailComposeViewController.h&gt;

@interface ViewController : UIViewController &lt;MFMailComposeViewControllerDelegate&gt;

- (IBAction)createEmail;

@end</code>

 

Кроме импорта MessageUI я добавил протокол MFMailComposeViewControllerDelegate (с помощью него мы будем получать уведомления о состоянии письма) и метод createEmail, в котором будет создавать само письмо (добавьте в xib-файл кнопку и свяжите ее нажатие с этим методом).

 

Теперь посмотрим как выглядит реализация класса ViewController:

 

ViewController.m

<code data-result="[object Object]">#import "ViewController.h"

@implementation ViewController

- (IBAction)createEmail {
    if ([MFMailComposeViewController canSendMail]) {
        MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
        picker.mailComposeDelegate = self;

        //Тема письма
        [picker setSubject:@"Hello from iMaladec!"];

        //Получатели
        NSArray *toRecipients = [NSArray arrayWithObject:@"first@example.com"]; 
        NSArray *ccRecipients = [NSArray arrayWithObjects:
                                 @"second@example.com", 
                                 @"third@example.com", nil]; 
        NSArray *bccRecipients = [NSArray arrayWithObject:@"fourth@example.com"]; 

        [picker setToRecipients:toRecipients];
        [picker setCcRecipients:ccRecipients];	
        [picker setBccRecipients:bccRecipients];

        NSString *emailBody = @"Это пример отправки Email с сайта iMaladec";
        [picker setMessageBody:emailBody isHTML:NO];

        [self presentModalViewController:picker animated:YES];
    } else {
        NSString *ccRecipients = @"second@example.com,third@example.com";
        NSString *subject = @"Hello from iMaladec!";
        NSString *recipients = [NSString stringWithFormat:
                                @"mailto:first@example.com?cc=%@&amp;subject=%@",
                                ccRecipients, subject];
        NSString *body = @"&amp;body=Это пример отправки Email с сайта iMaladec";

        NSString *email = [NSString stringWithFormat:@"%@%@", recipients, body];
        email = [email stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:email]];
    }
}

- (void)mailComposeController:(MFMailComposeViewController*)controller 
          didFinishWithResult:(MFMailComposeResult)result 
                        error:(NSError*)error 
{	
    NSString *message = nil;

    switch (result)
    {
        case MFMailComposeResultCancelled:
            message = @"Result: canceled";
            break;
        case MFMailComposeResultSaved:
            message = @"Result: saved";
            break;
        case MFMailComposeResultSent:
            message = @"Result: sent";
            break;
        case MFMailComposeResultFailed:
            message = @"Result: failed";
            break;
        default:
            message = @"Result: not sent";
            break;
    }

    NSLog(@"%@", message);

    [self dismissModalViewControllerAnimated:YES];
}

@end</code>

 

В первую очередь мы проверяем возможность отправки письма с помощью класса MFMailComposeViewController, если сделать это невозможно — формируем ссылку, которая откроет стандартное приложение Mail с заранее установленными темой письма и адресом получателя. При таком типе создания письма мы не сможем прикреплять к нему вложеные файлы и использовать другие фишки, речь о которых пойдет дальше в этом уроке.

 

В случае, если метод canSendMail возвратит логическое YES — мы создаем объект класса MFMailComposeViewController, присваиваем его делегатом объект класса, с которого его вызвали и заполняем поля значениями по умолчанию. В результате должна получится примерно следующая картинка:

 

 

В методе mailComposeController:didFinishWithResult:error: мы получаем состояние отправленного письма, ошибки об отправке (если таковы имеются) и ссылку на обект класса MFMailComposeViewController, который убираем с экрана.

 

Попробуем усложнить задачу, прикрепим к письму вложеные файлы. Пусть первый файл будет изображением, добавьте любую картинку в проект или скачайте эту. Второй файл будет текстовым. Мы создадим строку, и прикрепим ее к письму как файл. Посмотрим как это выглядит на практике.

 

<code data-result="[object Object]">- (IBAction)createEmail {
    if ([MFMailComposeViewController canSendMail]) {
        MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
        picker.mailComposeDelegate = self;

        //Тема письма
        [picker setSubject:@"Hello from iMaladec!"];

        //Получатели
        NSArray *toRecipients = [NSArray arrayWithObject:@"first@example.com"]; 
        NSArray *ccRecipients = [NSArray arrayWithObjects:
                                 @"second@example.com", 
                                 @"third@example.com", nil]; 
        NSArray *bccRecipients = [NSArray arrayWithObject:@"fourth@example.com"]; 

        [picker setToRecipients:toRecipients];
        [picker setCcRecipients:ccRecipients];	
        [picker setBccRecipients:bccRecipients];

        //Прикрепление файлов к письму
        NSData *imageData = UIImagePNGRepresentation([UIImage imageNamed:@"logo.png"]);
        [picker addAttachmentData:imageData mimeType:@"image/png" fileName:@"rainy.png"];

        NSString *report = @"No Errors";
        NSData *reportData = [report dataUsingEncoding:NSUTF8StringEncoding];
        [picker addAttachmentData:reportData mimeType:@"txt" fileName:@"report.txt"];

        NSString *emailBody = @"Это пример отправки Email с сайта iMaladec";
        [picker setMessageBody:emailBody isHTML:NO];

        [self presentModalViewController:picker animated:YES];
    } else {
        NSString *ccRecipients = @"second@example.com,third@example.com";
        NSString *subject = @"Hello from iMaladec!";
        NSString *recipients = [NSString stringWithFormat:
                                @"mailto:first@example.com?cc=%@&amp;subject=%@",
                                ccRecipients, subject];
        NSString *body = @"&amp;body=Это пример отправки Email с сайта iMaladec";

        NSString *email = [NSString stringWithFormat:@"%@%@", recipients, body];
        email = [email stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:email]];
    }
}</code>

 

Как оказалось, ничего сложного. Фишка заключается в том, что мы можем прикрепить любые данные, но перед этим их нужно конвертировать в NSData,  и передать в метод addAttachmentData:mimeType:fileName:, указав при этом тип данных и имя файла (с расширением). Внесенные изменения в коде сразу можно увидеть на экране:

 

 

Вы наверняка заметили второй параметр метода setMessageBody:isHTML:, до этого момента мы всегда передавали значение NO. Именно поэтому наш текст был не форматированым и убогим. Но у нас есть возможность придать ему красоты с помощью HTMLразметки. Тему создания HTML кода в этом уроке я подымать не буду, да и смысла в этом нет, в Интернете масса ресурсов на которых можна найти уроки на русском языке. Я предлагаю загрузить готовый файл HTML странички по этой ссылке и добавить его в проект. Соответственно, изменим и код. Я не буду переписывать весь метод createEmail, а лишь те строки, которые нузно заменить:

 

<code data-result="[object Object]">NSString *emailBody = @"Это пример отправки Email с сайта iMaladec";
[picker setMessageBody:emailBody isHTML:NO];</code>

 

на

 

<code data-result="[object Object]">NSString *path = [[NSBundle mainBundle] pathForResource:@"emailBody" ofType:@"html"];
NSString *emailBody = [NSString stringWithContentsOfFile:path 
                                                encoding:NSUTF8StringEncoding 
                                                   error:nil];
[picker setMessageBody:emailBody isHTML:YES];</code>

 

Теперь наше письмо получило более человеческий вид, с которого получатель может перейти на сайт проекта или на текущий урок.

 

 

Следует обратить внимание на то, что в этом случае логотип не прикреплен как вложеный файл. Он добавлен в письмо с помощьюHTML-разметки (<img alt=»» src=»http://www.imaladec.net/img/logo.png«/>) и при отсутствии соединение с Интернет не будет отображен в теле письма (но в таком случае и само письмо не получится отправить). Здесь вам на помощь может прийти урок Проверка соединения с Internet.

 

На последок хочу предупредить, что отправлять почту с симулятора у вас не получится. Дело в том, что на нем не стоит приложениеMail, а соответственно, вы не сможете настроить аккаунт с которого должны уходить письма. В вашем распоряжении лишь визуальная обертка того как будет выглядить редактор писем на устройстве.

Comments are closed.