I've implemented the already nth-times discussed open in iBook feature in my PDF viewer. And it works great when the PDF file does not contain spaces (example1.pdf, example2.pdf). When the PDF has some space (example 1.pdf) in the name clicking the open in iBook button does nothing.
NSString *fileURL = [(Documents *)(self.detailItem) url];
NSArray *subStrings = [fileURL componentsSeparatedByString:#"/"];
NSString *filePath = [[self documentsDirectory] stringByAppendingPathComponent:[subStrings lastObject]];
docIntController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:filePath]];
docIntController.delegate = self;
docIntController.UTI = #"com.adobe.pdf";
[docIntController presentOptionsMenuFromBarButtonItem:sender animated:YES];
Any suggestion is welcomed. Thanks :)
Since the filePath string is intended to be a URL, you likely need to run it through NSString -stringByAddingPercentEscapesUsingEncoding: before invoking fileURLWithPath:
Try enclosing the full path that you send to iBooks in quotes.
For example, use "example 1.pdf" instead of example1.pdf.
Related
I'm currently updating one of my apps to be iOS9 compatible, and I'm having trouble with the share to Instagram function. I'm using the Instagram hooks as stated on their developer site: (https://instagram.com/developer/mobile-sharing/iphone-hooks/)
The image I wish to share is being generated successfully, with the .igo suffix, and the functionality is still working as intended on iOS8. It just seems to have broken with the new version of iOS.
Here's the code for sharing to Instagram, using the UIDocumentInteractionController:
NSURL *instagramURL = [NSURL URLWithString:#"instagram://app"];
if ([[UIApplication sharedApplication] canOpenURL:instagramURL]) {
//convert image into .png format.
NSData *imageData = UIImagePNGRepresentation(image);
//create instance of NSFileManager
NSFileManager *fileManager = [NSFileManager defaultManager];
//create an array and store result of our search for the documents directory in it
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
//create NSString object, that holds our exact path to the documents directory
NSString *documentsDirectory = [paths objectAtIndex:0];
//add our image to the path
NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"insta.igo"]];
//finally save the path (image)
[fileManager createFileAtPath:fullPath contents:imageData attributes:nil];
CGRect rect = CGRectMake(0 ,0 , 0, 0);
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, self.view.opaque, 0.0);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIGraphicsEndImageContext();
NSString *fileNameToSave = [NSString stringWithFormat:#"Documents/insta.igo"];
NSString *jpgPath = [NSHomeDirectory() stringByAppendingPathComponent:fileNameToSave];
NSLog(#"jpg path %#",jpgPath);
NSString *newJpgPath = [NSString stringWithFormat:#"file://%#",jpgPath];
NSLog(#"with File path %#",newJpgPath);
NSURL *igImageHookFile = [[NSURL alloc]initFileURLWithPath:newJpgPath];
NSLog(#"url Path %#",igImageHookFile);
self.documentController = [UIDocumentInteractionController interactionControllerWithURL:igImageHookFile];
[self.documentController setDelegate:self];
[self.documentController setUTI:#"com.instagram.exclusivegram"];
[self.documentController presentOpenInMenuFromRect:rect inView:self.view animated:YES];
} else {
NSLog (#"Instagram not found");
}
It's probably worth mentioning I've already configured the URL schemes in the info.plist as required with the iOS9 changes.
The UIDocumentInteractionController does appear, and has the option 'Copy to Instagram'. Pressing this option just leads to the controller being dismissed, with no log messages or breakpoints being called on the controller's delegate (set to self; the view controller).
If anyone has, or has had trouble with this, it would be great to hear your thoughts, or better yet, how it was solved.
Update
It's also worth mentioning, on an iOS8 device, the Document Interaction Controller shows an 'Open in Instagram' button. The iOS9 device shows a 'Copy to Instagram' button.
After changing this line of code:
NSURL *igImageHookFile = [[NSURL alloc] initFileURLWithPath:newJpgPath];
to this:
NSURL *igImageHookFile = [NSURL URLWithString:newJpgPath];
The Instagram-share function for iOS 9 is now working. It seems that the previous line of code, converting the NSString to an NSURL would place "--://file" at the end of the URL path, which doesn't seem to register well with iOS 9. Simply converting the NSString to NSURL without initialising as a file URL seems to work.
You have to add a new key to your Info.plist file; it's an iOS 9 change for URL schemes. Check out the first answer for this question: iOS 9 not opening Instagram app with URL SCHEME. And just FYI, iOS 9 changes the "Open in Instagram" title for the UIDocumentInteractionController to "Copy to Instagram." Not sure why.
I want to import data from my iPhone to my application . up till now i have successfully imported Photo Library and music , but i also want to import pdf and other documents in my iOS app? How can i do that?
NSString *bundlePath = [[NSBundle mainBundle] resourcePath];
NSFileManager *mgr = [[NSFileManager alloc] init];
NSArray *allFiles = [mgr contentsOfDirectoryAtPath:bundlePath error:NULL];
for (NSString *fileName in allFiles)
{
if ([[fileName pathExtension] isEqualToString:#"pdf"])
{
NSString *fullFilePath = [bundlePath stringByAppendingPathComponent:fileName];
// fullFilePath now contains the path to your pdf file
// DoSomethingWithFile(fullFilePath);
NSLog(#"file: %#",fullFilePath);
}
}
NSURL *url = [[NSBundle mainBundle] URLForResource:#"" withExtension: #"pdf"];
NSLog(#"File: %#",url);
You can't do it in iOS 8 (I haven't checked 9 though). You can't even enlist your app (adding corresponding URL schemes) in the sharing menu of iBooks.
You have to associate your app with the PDF types which you want to open. You can do this by adding some parameters to your Info.plist.
There's a well-answered post which explains this:
How do I associate file types with an iPhone application?
You should also consider reading Apple's documentation and a blog post written by me.
When I use UIDocumentInteractionController to allow users to share via Instagram, it does work, it brings up the option for "open with" and "Instagram" as one of the options... the problem is that it also displays many other apps like "Facebook" and "Twitter"...
Is there any way I can make it only give the option of opening in the instagram app?
Instagram claims there is a way to do this: http://instagram.com/developer/iphone-hooks/ but they mention this:
"Alternatively, if you want to show only Instagram in the application list (instead of Instagram plus any other public/jpeg-conforming apps) you can specify the extension class igo, which is of type com.instagram.exclusivegram."
but I honestly have no clue what this part means, "extension class igo"
My code:
UIImage *imageToUse = [UIImage imageNamed:#"imageToShare.png"];
NSString *documentDirectory=[NSHomeDirectory() stringByAppendingPathComponent:#"Documents"];
NSString *saveImagePath=[documentDirectory stringByAppendingPathComponent:#"Image.ig"];
NSData *imageData=UIImagePNGRepresentation(imageToUse);
[imageData writeToFile:saveImagePath atomically:YES];
NSURL *imageURL=[NSURL fileURLWithPath:saveImagePath];
docController = [UIDocumentInteractionController interactionControllerWithURL:imageURL];
docController.delegate = self;
docController.annotation = [NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:#"This is the users caption that will be displayed in Instagram"], #"InstagramCaption", nil];
docController.UTI = #"com.instagram.exclusivegram";
[docController presentOpenInMenuFromRect:CGRectMake(1, 1, 1, 1) inView:self.view animated:YES];
Turns out to get the doc controller to only open in Instagram you just save your png or jpg file in format ".igo" file type extension, (Maybe stands for Instagram-Only?)
Changed the third line of code in my code to read this instead:
NSString *saveImagePath=[documentDirectory stringByAppendingPathComponent:#"Image.igo"];
(With "igo")
and then it worked! :)
Lower version of iOS 13:
NSString *saveImagePath=[documentDirectory stringByAppendingPathComponent:#"Image.igo"];
After iOS 13:
NSString *saveImagePath=[documentDirectory stringByAppendingPathComponent:#"Image.ig"];
This is what I'm trying to do:
Get a .pdf from external URL
Save it into my local disk
Display it in a WebView
Allow the user to move the .pdf to another app who can read .pdf
Everything from 1 to 3 works fine. But nothing is moved/shared to/with other apps. I can't understand what I'm doing wrong. This is what I'm doing.
How I save the pdf in the Documents folder (viewDidLoad):
// to save the pdf into local file system (tempString is the pdf url)
NSData *pdfData = [[NSData alloc]
initWithContentsOfURL:[NSURL URLWithString:tempString]];
NSString *resourceToPath = [[NSString alloc]
initWithString:[[[[NSBundle mainBundle] resourcePath]
stringByDeletingLastPathComponent]
stringByAppendingPathComponent:#"Documents"]];
NSString *filePAth = [resourceToPath stringByAppendingPathComponent:#"myPDF.pdf"];
[pdfData writeToFile:filePAth atomically:YES];
// to populate the WebView
NSURL *url2 = [NSURL fileURLWithPath:filePAth];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url2];
[my_web_view setUserInteractionEnabled:YES];
//[editoriale_view setDelegate:self];
[my_web_view loadRequest:requestObj];
In my viewDidLoad() function I create a button to allow the user to open a list of apps who can read .pdf files:
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemBookmarks target:self
action:#selector(show_Button)];
And here's my show_Button function:
-(void)show_Button {
NSString *resourceToPath = [[NSString alloc]
initWithString:[[[[NSBundle mainBundle] resourcePath]
stringByDeletingLastPathComponent]
stringByAppendingPathComponent:#"Documents"]];
NSString *filePAth = [resourceToPath
stringByAppendingPathComponent:#"myPDF.pdf"];
NSLog(#"filePath = %#", filePAth);
NSURL *url2 = [NSURL fileURLWithPath:filePAth];
NSLog(#"url2 = %#", url2);
UIDocumentInteractionController *docContr = [UIDocumentInteractionController
interactionControllerWithURL:url2];
[docContr presentOpenInMenuFromRect:CGRectZero inView:self.view animated:YES];
}
When I try this on my device everything works fine until I tap on one of the icons in the list (i.e. the iBooks one). Then the app closes (it doesn't crash, it simply closes).
Here's what the console prints for the two logs I put in the show_Button function:
1. filePath = /Users/[MY_USER]/Library/Application Support/iPhone
Simulator/6.1/Applications/[MY_EXAD_APP_ID]/Documents/myPDF.pdf
2. url2 = file://localhost/Users/[MY_USER]/Library/Application%20Support/
iPhone%20Simulator/6.1/Applications/[MY_EXAD_APP_ID]/Documents/myPDF.pdf
Anyone wants to try to make me understand what I'm doing wrong? I'm using Xcode 4.6. I browsed my iPhone app file system with a third-party software and the file "MyPDF.pdf" actually IS in the Documents" folder, and that's clear because the WebView is correctly populated.
Change CGRectZero to self.view.bounds when you display the document controller.
Solved. I had not implemented the UIDocumentenInteractionController delegate in the .h file. Now I have and everything works fine. Thank you to #trojanfoe for the useful hint.
I have a pdf file that I would like to open with a specific app, like iBooks. I would like to have it so that the user can set what program they want to open it with among the ones currently installed that can handle it. Here is the code I have that lets me do just that, only the user has to select which app to use each time (an extra step I'd like to avoid):
NSString *stringVariable = cell.textLabel.text;
NSString *homeDir = NSHomeDirectory();
homeDir = [NSString stringWithFormat: #"%#/%#", homeDir, #"Documents"];
NSString * filePath = [NSString stringWithFormat:#"%#/%#", homeDir, stringVariable];
documentController =
[UIDocumentInteractionController
interactionControllerWithURL:[NSURL fileURLWithPath:filePath]];
documentController.delegate = self;
[documentController retain];
documentController.UTI = #"com.adobe.pdf";
[documentController presentOpenInMenuFromRect:CGRectZero
inView:self.view
animated:YES];
So stringVariable contains the name of the document in question, and then it displays the various apps capable of running it. If I could somehow populate that into a selector of some kind so the user can select the default app to use, that would be great, but if I have to settle for setting it to a specific app myself (like iBooks), that would work too.
Use UTI param. For instance, if you have 5 apps that support Instagram url scheme and file types, just use this:
documentController.UTI = #"com.instagram.exclusivegram";
It will not make the selection for you, but it will limit the choice to the app want.