Iphone 在UIActivity期间显示UIAlertView:activityViewController

Iphone 在UIActivity期间显示UIAlertView:activityViewController,iphone,ios,uialertview,grand-central-dispatch,uiactivity,Iphone,Ios,Uialertview,Grand Central Dispatch,Uiactivity,我有一套UIActivities,我将数据准备成给定的格式,然后将其附加到用户可以发送的电子邮件中。我正在使用UIActivity的一个子类,我正在做-(void)activityViewController中的所有工作: - (UIViewController *)activityViewController { [self.alert show]; NSString *filename = [NSString stringWithFormat:@"%@.gpx", self

我有一套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;
}
我遇到的具体问题是,在dispatch\u sync完成之前,UIAlertView实际上不会显示。我意识到dispatch_sync可能会在主线程等待时阻塞主线程,但问题是我需要等待直到生成附件,然后再从该方法调用返回(MFMailComposeViewController文档说,一旦显示视图,就不能添加附件)

当主线程必须等待完成的非平凡任务必须运行时,如何获得alertview来显示

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

我必须将我的主ViewController(显示活动表的主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];
        });
    });
}

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


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

同步请求意味着您必须等待完成。。。使用异步请求。@如果我这样做,则说明附件是在显示邮件VC后生成的,这意味着未添加附件。(显示VC后阻止添加附件)您应该在块中添加附件,然后在完成后显示邮件composer@TheTiger不太确定我是否明白你的意思。将其添加到块中会起作用,但使其异步会导致在块完成之前显示VC。UIActivities的工作方式是,您必须返回UIViewController以从该方法显示给用户,我不能推迟到块完成后再显示它。