I have a set of UIActivities where I prepare my data into a given format and then attach it to an email the user can send. I'm using a subclass of UIActivity and I'm doing all the work in -(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;
}
The specific issue I'm running into is that the UIAlertView doesn't actually show until the dispatch_sync completes. I realize the dispatch_sync might(?) be blocking the main thread as it waits, but the problem is I need to wait until the attachment is generated before returning from that method call (MFMailComposeViewController docs say you can't add attachment once the view is presented).
How can I get an alertview to show while a non-trivial task the main thread has to wait for completion has to run?
Ick.
For what it's worth, I had to give up (after 4 hours of fighting with all kinds of blocks, performOnThread, etc) on using the activityViewController method to directly return a UI and instead switch to the performActivity method. PerformActivity is supposed to be for UI-less activities, but it's the only async-compatable one.
I have to set my main ViewController (the one showing the activity sheet) as a delegate to the UIActivities, then call my delegate back with the message VC once the export is ready: