0

我有一组 UIActivities,我将数据准备为给定格式,然后将其附加到用户可以发送的电子邮件中。我正在使用 UIActivity 的子类,我正在做所有的工作-(void)activityViewController

- (UIViewController *)activityViewController
{
    [self.alert show];

    NSString *filename = [NSString stringWithFormat:@"%@.gpx", self.activity.title];
    __block MFMailComposeViewController *mailComposeVC = [[MFMailComposeViewController alloc] init];
    mailComposeVC.mailComposeDelegate = self;
    [mailComposeVC setSubject:[NSString stringWithFormat:@"GPX export for %@ activity", self.activity.title]];
    [mailComposeVC setMessageBody:@"Generated with Slopes" isHTML:NO];

    dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
        CBCFileExporter *exporter = [[CBCFileExporter alloc] init];
        NSData *exportContents = [exporter exportActivity:self.activity inFileFormat:CBCFileExportTypeGPX error:nil];
        [mailComposeVC addAttachmentData:exportContents mimeType:@"application/gpx+xml" fileName:filename];
    });

    [self.alert dismissWithClickedButtonIndex:0 animated:YES];

    return mailComposeVC;
}

我遇到的具体问题是 UIAlertView 直到 dispatch_sync 完成才真正显示。我意识到 dispatch_sync 可能(?)在等待时阻塞了主线程,但问题是我需要等到附件生成后再从该方法调用返回(MFMailComposeViewController 文档说一旦视图是你就不能添加附件提出了)。

当主线程必须等待完成的非平凡任务必须运行时,如何获得警报视图以显示?

4

2 回答 2

0

鉴于邮件视图控制器明确禁止在邮件撰写视图控制器出现后添加附件,您可能需要在此处创建并显示带有不确定进度指示器的“插页式”视图控制器,开始导出过程在后台,然后当该过程完成时,创建并使用附件完全填充邮件撰写视图控制器,然后呈现它。

在呈现之前将其完全填充的要求意味着不可能有简单的“在后台执行此操作并给我回电”的方法。

于 2013-08-07T16:49:32.613 回答
0

伊克。

对于它的价值,我不得不放弃(在与各种块、performOnThread 等进行了 4 小时的斗争之后)使用 activityViewController 方法直接返回 UI,而是改用 performActivity 方法。PerformActivity 应该用于无 UI 的活动,但它是唯一可异步兼容的活动。

我必须将我的主 ViewController(显示活动表的那个)设置为 UIActivities 的委托,然后在导出准备好后用消息 VC 调用我的委托:

- (void)performActivity
{
    __block UIAlertView *alert = [[UIAlertView alloc] init];
    alert.title = @"Generating Export";
    [alert show];

    //get rid of the activity sheet now - can't present the mail modal if this is active
    [self activityDidFinish:YES];

    __block CBCGPXEmailActivity *weakSelf = self;
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
        CBCFileExporter *exporter = [[CBCFileExporter alloc] init];
        NSString *filename = [NSString stringWithFormat:@"%@.gpx", weakSelf.activity.title];
        NSData *exportContents = [exporter exportActivity:weakSelf.activity inFileFormat:CBCFileExportTypeGPX error:nil];

        //dispatch after to make sure there was time to remove the action sheet
        double delayInSeconds = 0.1;
        dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
        dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
            MFMailComposeViewController *mailComposeVC = [[MFMailComposeViewController alloc] init];
            [mailComposeVC setSubject:[NSString stringWithFormat:@"GPX export for %@ activity", weakSelf.activity.title]];
            [mailComposeVC setMessageBody:@"Generated with Slopes" isHTML:NO];
            [mailComposeVC addAttachmentData:exportContents mimeType:@"application/gpx+xml" fileName:filename];

            [weakSelf.delegate showMailViewController:mailComposeVC];
            [alert dismissWithClickedButtonIndex:0 animated:YES];
        });
    });
}
于 2013-08-07T16:35:55.457 回答