Objective-c UIDocumentInteractionController loads gray screen - ios

I am trying to preview a UIDocumentInteractionController like so:
NSString* filePath = [[NSBundle mainBundle] pathForResource:#"FLW-0032 Design Sketches" ofType:#"pdf"];
_previewItemURL = [NSURL URLWithString:filePath];
UIDocumentInteractionController *documentInteractionController =[UIDocumentInteractionController interactionControllerWithURL:_previewItemURL];
documentInteractionController.delegate = self;
[documentInteractionController presentPreviewAnimated:YES];
And all I get is the gray screen with the file name. The file is 5.5MB
What am I doing wrong?
Here is my delegate method:
- (UIViewController *) documentInteractionControllerViewControllerForPreview: (UIDocumentInteractionController *) controller {
return self.navigationController;
}
I am seeing this in my console log
[Snapshotting] Snapshotting a view (0x108c80800,
_UIButtonBarStackView) that has not been rendered at least once requires afterScreenUpdates:YES. 2018-03-07 20:39:16.169613-0500
SchedulingiPadApplication[417:61893] [default] Couldn't issue file
extension for url:
file:///var/containers/Bundle/Application/23540D89-0841-4F12-A6A4-A2840D4076F4/SchedulingiPadApplication.app/FLW-0032%20Design%20Sketches.pdf
PreviewItem
This happens when I a presenting the documentInteractionController

You need to use NSURL fileURLWithPath:, not URLWithString:.
Better yet, use NSBundle URLForResource:withExtension: to get the NSURL directly.

Related

presentOpenInMenuFromRect not working DocumentHandler.h - QuickLook

I'm using documenthandler cordova plugin in where if I click the button I get the pdf in the document handler from the url which works fine, so that I can save the pdf into iBooks.
Now, instead of opening the document in the viewer and clicking the share button and then click again to save into iBooks I need to be able to trigger the share button without opening the document. I know this can be done using presentOpenInMenuFromRect instead of presentViewControllerbut it does not work for some reason, code below:
#import "DocumentHandler.h"
#implementation DocumentHandler
- (void)HandleDocumentWithURL:(CDVInvokedUrlCommand*)command;
{
CDVPluginResult *commandResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:#""];
__weak DocumentHandler* weakSelf = self;
dispatch_queue_t asyncQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(asyncQueue, ^{
NSDictionary* dict = [command.arguments objectAtIndex:0];
NSString* urlStr = dict[#"url"];
NSURL* url = [NSURL URLWithString:urlStr];
NSData* dat = [NSData dataWithContentsOfURL:url];
NSString* fileName = [url lastPathComponent];
NSString* path = [NSTemporaryDirectory() stringByAppendingPathComponent: fileName];
NSURL* tmpFileUrl = [[NSURL alloc] initFileURLWithPath:path];
[dat writeToURL:tmpFileUrl atomically:YES];
weakSelf.fileUrl = tmpFileUrl;
dispatch_async(dispatch_get_main_queue(), ^{
QLPreviewController* cntr = [[QLPreviewController alloc] init];
cntr.delegate = weakSelf;
cntr.dataSource = weakSelf;
UIViewController* root = [[[UIApplication sharedApplication] keyWindow] rootViewController];
[root presentViewController:cntr animated:YES completion:nil];//this works fine and open the document with share button
CGRect rect = CGRectMake(0, 0, 1024, 768);
[root presentOpenInMenuFromRect:rect inView:self.view animated:YES]; // this doesn't work where
//I want to see only sharing options
//here are errors,one of them is /Property'view' not found on object of type ''DocumentHandler
});
[weakSelf.commandDelegate sendPluginResult:commandResult callbackId:command.callbackId];
});
}
#pragma mark - QLPreviewController data source
- (NSInteger) numberOfPreviewItemsInPreviewController: (QLPreviewController *) controller
{
return 1;
}
- (id <QLPreviewItem>) previewController: (QLPreviewController *) controller previewItemAtIndex: (NSInteger) index
{
return self;
}
#pragma mark - QLPreviewItem protocol
- (NSURL*)previewItemURL
{
return self.fileUrl;
}
#end
I need help please :(
EDIT: see the image what I'm trying to achieve:
presentOpenInMenuFromRect is a UIDocumentInteractionController method. I do not think you are using one in this code, unless your root view controller is a UIDocumentInteractionController, which would be very very weird.
Instead of instantiating and presenting a QLPreviewController, instantiate an UIDocumentInteractionController and present the popover from the rect corresponding to the document's icon.
To do this, check out the UIDocumentInteractionController documentation. You'll see there is an interactionControllerWithURL: method that you can use to instantiate an UIDocumentInteractionController pointed at your file. You can then call
presentOpenInMenuFromRect:inView:animated: to show the popover you want.

Open local PDF file in iBooks

I am trying to open a PDF file that I have stored locally within my app in iBooks. The app currently has a list of "literature" in a table view and when each cell is tapped the app segues to a webView that displays the PDF file (works great). I have made a BarButton at the top right in navBar to allow the user to open the PDF in iBooks (so they can store it on his/her device).
So far the button will open a UIDocumentInteractionController that displays all apps on the device that can open the file (after checking if iBooks is installed). Then when I click the iBooks icon the app crashes. I was able to revise the code so that iBooks opens without crashing, but the PDF file is not carried through so it's kind of pointless (code below is reverted back to when it crashes).
Code below is inside the IBAction of the barButton...
NSString *path = [[NSBundle mainBundle] pathForResource:litFileName ofType:#"pdf"];
NSURL *targetURL = [NSURL fileURLWithPath:path];
UIDocumentInteractionController *docController = [UIDocumentInteractionController interactionControllerWithURL:targetURL];
if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:#"itms-bookss:"]])
{
[docController presentOpenInMenuFromRect:CGRectZero inView:self.view animated:YES];
NSLog(#"ibooks is installed");
}
else
{
NSLog(#"no ibooks installed");
}
Fixed it! Took some time away from the project and after coming back two weeks later I figured it out in <15 minutes.
So it was a memory issue for the docController and by declaring in the .h file and using (retain) it works perfectly. I was also able to use the [NSBundle mainBundle] method as well.
.h
#property (retain)UIDocumentInteractionController *docController;
.m
#synthesize docController;
//in bar button IBAction
NSString *path = [[NSBundle mainBundle] pathForResource:litFileName ofType:#"pdf"];
NSURL *targetURL = [NSURL fileURLWithPath:path];
docController = [UIDocumentInteractionController interactionControllerWithURL:targetURL];
if([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:#"itms-books:"]]) {
[docController presentOpenInMenuFromRect:CGRectZero inView:self.view animated:YES];
NSLog(#"iBooks installed");
} else {
NSLog(#"iBooks not installed");
}
On iOS 8 the layout of the file system changed and sharing files directly from the main bundle no longer works. Copy the file to the documentsdirectory and share it from there.
Here is how to create the file path:
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSString *fileName = [NSString stringWithFormat:#"%#.pdf",litFileName];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:fileName];
NSURL *url = [NSURL fileURLWithPath:filePath];

Load .ics file to add calendar event from application

To load .ics file from url I am using open url method as below
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:fullURL]];
It's working fine.
But I want to load .ics file from application's bundle without URL. eg., I have file is test.ics file How can I load this file, can we load anyway it without URL?
You can load the ics file locally
NSURL *path = [[NSBundle mainBundle] URLForResource:#'icsName' withExtension:#'ics'];
[[UIApplication sharedApplication] openURL:path];
- (IBAction)displayICS:(id)sender
{
NSString *path = [[NSBundle mainBundle] pathForResource:#"test" ofType:#"ics"];
NSURL *url = [NSURL fileURLWithPath:path];
UIDocumentInteractionController *dc = [UIDocumentInteractionController interactionControllerWithURL:url];
dc.delegate = self;
[dc presentPreviewAnimated:YES];
}
-(UIViewController *)documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController *)controller
{
return self;
}

iOS QLPreviewController load file from remote server URL

What is approach should be used while loading files from remote server on QLPreviewController?
When should we download files using my server API to load them on QLPreviewController.
I am adding QLPreviewController as subview to my current view.
I can use datasource method to make call to download file from server.
- (id<QLPreviewItem>)previewController:(QLPreviewController *)controller previewItemAtIndex:(NSInteger)index
But once file is downloaded i need to reload QLPreviewController, where this should be done
For images i would like to image gallery view so that swipe to view images downloaded from server.
Can anyone point me to any tutorial to load images from remote server URL
To show any file that supports QLPreviewController, the url should
be the fileURL.
(id<QLPreviewItem>)previewController:(QLPreviewController *)controller previewItemAtIndex:(NSInteger)index
It always returns fileURL - if you will use any other URL, it will crash. After downloading is over save the file in documents directory and then push to preview.
- (void)saveFileInDocDirectoryWithFileName:(NSString *)title{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docPath_ = [paths objectAtIndex:0];
NSString *filePath = [ docPath_ stringByAppendingPathComponent:title];
self.fileURL = [NSURL fileURLWithPath:filePath];
[self pushToPreViewWithURL:fileURL];
}
- (void)pushToPreViewWithURL:(NSURL *)filePathURL{
QLPreviewController *previewController = [[QLPreviewController alloc] init];
previewController.dataSource = self;
previewController.delegate = self;
// start previewing the document at the current section index
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[self.navigationController pushViewController:previewController animated:YES];
}];
}
Then in delegate method, return fileURL:
- (id)previewController:(QLPreviewController *)previewController previewItemAtIndex:(NSInteger)idx {
return self.fileURL;
}

UIWebView Delegates Not Triggering ? iOS

I am loading a local HTML into a UIWebView as follows :
- (void)viewDidLoad
{
[super viewDidLoad];
//Setup our UIWebView
webView = [[UIWebView alloc] initWithFrame:self.view.bounds];
webView.delegate = self;
webView.scalesPageToFit = YES;
webView.userInteractionEnabled = YES;
[self.view addSubview:webView];
...
[self loadWebPage];
}
- (void)loadWebPage {
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"index" ofType:#"html"]];
[webView loadRequest:[NSURLRequest requestWithURL:url]];
}
And in the header :
#interface ViewController : UIViewController <UIWebViewDelegate>
However for some reason my webview delegates are not being called :
- (void)webViewDidStartLoad:(UIWebView *)webView {
NSLog(#"Starting HTML Load Process");
}
- (void)webViewDidFinishLoad:(UIWebView *)webViewRef {
NSLog(#"Web View Finished Loading Method");
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
NSLog(#"Error loading HTML ! %#", error);
}
Can anyone suggest why ?
Thanks !
Called the method [self loadWeb];
But on definition the method is - (void)loadWebPage;
Is it typo?
The only way I can reproduce is this by declaring the webView #property as weak. Can you confirm you are declaring it as a strong reference?
how did you declare your UIWebView instance variable, as a strong or weak? If weak make it strong.
The problem is that this call.
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"index" ofType:#"html"]];
Looks like you're loading the HTML from inside your bundle. This means you need to confirm that all the additional files (.js, .css, and any media files) also need to be present in your bundle.
So the first thing need to check fileURLWithPath: point either it's returning nil or not. If it's not then it means that .html page resolved, however the additional files not resolved as part of the request because it's not placed on the same "index.html" path.
First you need to confirm the directory structure of your "index.html" and all the additional files used inside the page. In order to do that, you have to right click on binary .app in your "build" directory in the finder and then select "Show Package contents".
binary (.app) > right click > Show Package contents
This shows what the app's main bundle contains. Look inside for your HTML file. If it's in a folder, that folder name needs to be in the inDirectory parameter of the pathForResource call. If it's on the top-level then you don't have a folder reference. Either delete & re-drag it into project or use the pathForResource version without inDirectory.
The best way to don't setup the base path or relative path for the resources inside .html page (.js, .css and images) because it don't work. Copy all the additional resources next to "index.html" file so it would be easy to resolve on runtime from bundle.
NSString *path = #"<Index.html Path>";
NSURL *url = [NSURL URLWithString: [path lastPathComponent]
relativeToURL: [NSURL fileURLWithPath: [path stringByDeletingLastPathComponent]
isDirectory: YES]];
Try this
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"index" ofType:#"html"]isDirectory:NO];

Resources