I'm using the UIDocumentInteractionController in iOS 7.1 and it's performing really badly.
I'm using it in a UICollectionViewController to view documents in a collection view.
On pressing an item in the collection view, it takes about around 6 (yes, that's six) seconds to appear. From a user experience perspective, they've pressed the screen a few more times before it appears because it takes so long.
I'm using the same code since iOS 6, but it seems particularly bad now. If anyone has any thoughts as to how I can speed things up, that would be greatly appreciated.
Essentially, I have the following in my header file:
interface MyViewController : UICollectionViewController <UIDocumentInteractionControllerDelegate>
{
UIDocumentInteractionController *docController;
}
@end
and in the implementation, I'm just doing the following:
In viewDidLoad (recently moved to here to see if it improves things):
docController = [[UIDocumentInteractionController alloc] init];
docController.delegate = self;
And then in the collectionView:didSelectItemAtIndexPath: I'm doing this:
NSURL *fileURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:document.Link ofType:@"" ]];
[docController setURL:fileURL];
PresentationViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"DocumentCell" forIndexPath:indexPath];
CGRect rect1 = cell.frame;
bool didShow = [docController presentOptionsMenuFromRect:rect1 inView:collectionView animated:YES];
where document is just a class with a string for the URL.
Let me know if you need any further detail.
Thanks in advance for any assistance anyone can provide.
-- Update: After some NSLogs, I noticed that it's definitely the following line that's slow:
bool didShow = [docController presentOptionsMenuFromRect:rect1 inView:collectionView animated:YES];
TL;DR:
The method you are using is a synchronous request that uses your document data for find which apps are capable of reading your file. You need to swap with the asynchronous version that restricts the enumeration to only apps that can parse your file type.
Remove this method:
- (BOOL)presentOptionsMenuFromRect:(CGRect)rect
inView:(UIView *)view
animated:(BOOL)animated
And replace with this method:
- (BOOL)presentOpenInMenuFromRect:(CGRect)rect
inView:(UIView *)view
animated:(BOOL)animated
Excerpt from the Apple Docs:
This method is similar to the presentOptionsMenuFromRect:inView:animated: method, but presents a menu restricted to a list of apps capable of opening the current document. This determination is made based on the document type (as indicated by the UTI property) and on the document types supported by the installed apps. To support one or more document types, an app must register those types in its Info.plist file using the CFBundleDocumentTypes key.
If there are no registered apps that support opening the document, the document interaction controller does not display a menu.
This method displays the options menu asynchronously. The document interaction controller dismisses the menu automatically when the user selects an appropriate option. You can also dismiss it programmatically using the dismissMenuAnimated: method.
I was encountering a similar problem with:
UIDocumentInteractionController.presentPreviewAnimated
It would take an incredibly long time to complete. I found adding a brief delay between saving the file to be previewed and presenting the preview fixed the problem:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(100 * NSEC_PER_MSEC)), dispatch_get_main_queue(), {
self.controller.presentPreviewAnimated(false)
})
Swift 4.2
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.controller.presentPreviewAnimated(false)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With