iOS: как создать/подготовить пользовательское вложение электронной почты в фоновом режиме, когда уже отображается представление для создания почты?

Я хотел бы поделиться пользовательским содержимым моего приложения для iOS 6.0 по электронной почте.

Но поскольку мой контент требует некоторого времени для подготовки, прежде чем я смогу поделиться им, я не могу сразу же показать представление создания почты, когда пользователь нажимает кнопку «Поделиться». К сожалению, MFMailComposeViewController нуждается во всех вложениях с самого начала, поэтому мне нужно дождаться вложения, прежде чем я смогу инициализировать и показать MFMailComposeViewController (как это предлагается здесь: UIActivityView прикрепить файл к электронной почте )

-- Изменить после прочтения ответа Сапана: я ищу поведение, подобное UIActivityViewController, при совместном использовании, например. видеофайл, который еще нужно создать: пользователь нажимает кнопку «Поделиться», и сразу же появляется UIActivityController. Вложение создается в фоновом режиме, и его создание не прерывает работу пользователя. --

Я попробовал UIActivityViewController с его хорошей асинхронной функцией UIActivityItemProvider, но, к сожалению, это работает только для вложений с общедоступными типами mime, такими как изображения и видео. Мой пользовательский «элемент» NSData просто игнорируется не только для обмена на Facebook (что имеет смысл), но и для обмена электронной почтой. Или я что-то не так делаю здесь:

MyUIActivityItemProvider *myCustomDocProvider = [[MyUIActivityItemProvider alloc] initWithPlaceholderItem:[[NSData alloc]init] andCustomInfoToCreateNSDataFrom:customAppInfo];
UIActivityViewController *activityVC = [[UIActivityViewController alloc]initWithActivityItems:@[myTextString, myCustomDocProvider] applicationActivities:nil];
[self presentViewController:activityVC animated:YES completion:nil];

Я уже думаю о создании собственного пользовательского представления для компоновщика электронной почты, чтобы я мог создавать вложения в фоновом режиме, пока/после того, как пользователь печатает. Но я не хочу. Мне нравится идея «согласованности элементов пользовательского интерфейса», о которой я читал в HIG.

Что я могу сделать?


person Goodsquirrel    schedule 12.11.2012    source источник
comment
Я только начинаю работать со stackoverflow. Что я сделал не так в своем вопросе? Почему меня заминусовали? Разве я недостаточно исследовал давно решаемую проблему? Или это мой стиль? Слишком долго? Слишком непонятно?   -  person Goodsquirrel    schedule 13.11.2012
comment
Корявый. Но что бы вы хотели, чтобы произошло, если пользователь нажал «Отправить» (в MFMailComposeViewController) ДО того, как ваш процесс завершил создание вложения? На данный момент нет хорошего варианта (изменение почты после того, как она якобы была отправлена ​​- если бы вы вообще могли - было бы действительно странно). Я не вижу хорошей альтернативы тому, чтобы терпеть задержку, прежде чем разрешить им отправлять почту. Возможно, отменяемый занятый ящик сделает это терпимым.   -  person jbbenni    schedule 15.03.2014


Ответы (3)


Вы можете создать метод следующим образом, а затем вызвать его, используя [self performSelectorInBackground:@selector(sendMail)];

-(void) sendMail
{
    // Prepare the data

    // Attach the data
    MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
    [picker addAttachmentData:myData mimeType:@"<YOUR-MIME-TYPE>" fileName:@"Filename"];

    // Show compose view controller on the main thread
    dispatch_async(dispatch_get_main_queue(), ^(void) {
        // Fill out the email body text
        NSString *emailBody = @"Body";
        [picker setMessageBody:emailBody isHTML:NO];
        [self presentModalViewController:picker animated:YES];
    });
}
person Sapan Diwakar    schedule 12.11.2012
comment
Большое спасибо за ваш ответ. К сожалению, это не решает проблему. Потому что, хотя и не блокируя основной поток, MFMailComposeViewController по-прежнему не отображается при нажатии кнопки, а только после завершения создания вложения в фоновом режиме. Если создание вложения занимает 3 секунды, может быть, даже 10, это не лучший пользовательский опыт. Извините, если мой вопрос был недостаточно ясен: я ищу способ немедленно показать mailComposeVC при обработке вложения в фоновом режиме (так же, как UIActivityViewController делает, например, с видео). - person Goodsquirrel; 13.11.2012

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

Не оптимально, потому что это может привести к сбою после отправки электронного письма, но, вероятно, это лучший выбор.

person Ortwin Gentz    schedule 11.12.2012

Это можно сделать, используя логическое значение в вашем myCustomDocProvider, чтобы удерживать возврат элемента до завершения построения файла. Если вы хотите отображать прогресс или отображать индикатор активности в главном представлении, вы можете сделать это, вызвав его из основного потока. Вот фрагмент кода в действии:

Настройте Контроллер представления активности в вашем провайдере с этой функцией, чтобы загрузить представление прогресса.

self.parentViewController = parentVc;

Вот функция элемента с блокировкой и загрузкой представления обратной связи.

self.wait = true;

[self prepareFile:^(){
    [self performSelectorOnMainThread:@selector(dismissProgressView) 
                              withObject:nil waitUntilDone:NO];
}];

[self performSelectorOnMainThread:@selector(loadProgressView) 
                              withObject:nil waitUntilDone:NO];

while (self.wait) {
    [self performSelectorOnMainThread:@selector(updateProgressView) 
                                     withObject:nil waitUntilDone:NO];
}

return self.completedUrl;

Затем вы можете создать три функции, которые вызываются в основном потоке, чтобы отображать представление о ходе выполнения, обновлять представление о ходе выполнения, ожидая завершения файла. При реализации функции rejectProgressView убедитесь, что для логического значения ожидания задано значение false после завершения функции rejectViewController.

person Escape Velocity Apps    schedule 29.03.2013
comment
Спасибо за Ваш ответ. Если я правильно понимаю, вы предлагаете (как это сделал Сапан Дивапар) приостановить показ MFMailComposeVC до тех пор, пока документ не будет готов. Но, кроме того, вы также предлагаете полностью заблокировать основной поток (показывая индикатор выполнения). Но то, что я искал, было решением для подготовки документа в фоновом режиме, в то время как MFMailCompositingVC уже находится на экране и может использоваться. - person Goodsquirrel; 19.04.2013
comment
что вы имеете в виду, использовать логическое значение в вашем провайдере? Например, вернуть логическое значение из activityViewController:itemForActivityType? - person diachedelic; 23.10.2013