Open Local PDF in Safari in iOS - ios

Let's say that myURL pointed to a PDF which was obtained by doing:
myURL = [[NSBundle mainBundle] URLForResource:#"my" withExtension:#"PDF"];
I can call [[UIApplication sharedApplication] canOpenURL:myURL] and see that it returns YES.
However, when I call [[UIApplication sharedApplication] openURL:myURL], nothing happens and it returns NO.
Is there a way to have this work?
Yes, I know I could use a UIWebView to have it open the PDF, but in this instance, I need the Safari App to open it, if possible. I am aware the natural consequence of this will be for it to exit my application. This behavior would be acceptable in this case.
Thank you.

This is not currently possible.

As far as I know it is not possible to hand a local PDF file off to MobileSafari.
But you can easily hand off a local PDF file to any locally installed application that acts as a PDF viewer. i.e., iBooks, GoodReader, etc. If this is sufficient, you should take a look at UIDocumentInteractionController. It will present a menu of apps, and let the user choose one to open the file in. Unfortunately, Safari itself does not register as a PDF viewer.
(If you did decide to present PDFs yourself, the QLPreviewController will display the file and give you the "send to other app" functionality.)

Related

iOS open broswer from and App and close it at some point and return to the App?

I have an request but I don't know if it is possible. I need to open a browser from my App (which I know that is possible and I know how to do). Then after some browsing and navigation in the browser it will land at a page which I can control. In that moment I need to close the browser and go back to my application.
Is it possible to do that? And if can you provide me some lead how to do that?
you can use URLScheme in you info.plist
https://developer.apple.com/library/ios/featuredarticles/iPhoneURLScheme_Reference/Introduction/Introduction.html#//apple_ref/doc/uid/TP40007899
for test you can open your app form other app also
with
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"yourScHeme://"]];
Instead of opening browser from your application, you can use UIWebview to load web content so that no need to do transition from your app to browser.
Here is tuturial which may help you.
http://iosdeveloperzone.com/2013/11/17/tutorial-building-a-web-browser-with-uiwebview-revisited-part-1/

Add "Edit in Excel" or "Edit photo" extension

I checked the latest Dropbox and Excel for iOS. In Dropbox we get an edit button. On click it opens Excel's extension where you can edit the file.
After save, changes are reflected in the Dropbox file too.
I want to add such a button. Also I'd like to add such a button to images to open them in available "photo editing" apps.
How to check if file (image, xls, doc or any other) can be opened to edit?
Code so far:
UIDocumentPickerViewController *documentPicker = [[UIDocumentPickerViewController alloc] initWithURL:url inMode:UIDocumentPickerModeExportToService];
documentPicker.delegate = self;
documentPicker.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentViewController:documentPicker animated:YES completion:nil];
Also tried changing mode to UIDocumentPickerModeMoveToService...
As per apple docs
Move a local document. The user selects an external destination. The document picker moves the document; however, you can still access the document as an external document, letting the user edit the document in place.
But I tried all four modes. Did not show excel option.
UIDocumentPickerModeImport,
UIDocumentPickerModeOpen,
UIDocumentPickerModeExportToService,
UIDocumentPickerModeMoveToService
The only way to communicate with other iOS apps "locally" is using what is called URLSchemes.
This is the documentation to use URLScheme with the MSOffice apps.
https://msdn.microsoft.com/en-us/library/office/dn911482.aspx
Answering the specific question:
How to check if file (image, xls, doc or any other) can be opened to edit?
You can use the UIApplication method called canOpenURL to check if the current device responds to a specific URLScheme and if it does, you can call the app to edit you file. The same can be applied to other apps that you want to open. You just need to see if the app have URLScheme support.
Remembering that in iOS 9 you need to add the URLs you want to call during the app life in the Info.plist. Otherwise, the canOpenURL method will always returno NO.
This code illustrates the approach. However, it is to search some navigation apps. Just like tapping a shared friend location in WhatsApp.
https://snipt.net/wallaaa/using-url-schemes/
The result:
it's 2017 and iOS 11 and it's still not possible to edit files in place.
Dropbox is using MS Office API to provide http links to download and upload changed document.
Direct edit of the file is only possible if FileProvider extension is implemented and file was opened in editor app via document picker (which grants access to the file in sandbox).
Photo editing is allowed because editor is made by Apple (Photos app).

Handling ics data in UIWebView

I have an app which uses a UIWebView and cordova/PhoneGap. One section of the app has a 'Download Calendar' feature, which has been giving me a lot of issues on the native iOS side. The basic function of Download Calendar is an ajax call (type: POST) which returns formatted ics data. In mobile safari, this functions perfectly. A table view will slide up from the bottom and give me the option to add the listed events to my phone's calendar. I think this is just how safari normally handles ics files. Now for my issue...
UIWebView doesn't seem to want to behave this way. When I tap "Download Calendar" nothing happens. To get the ics data, I used an NSURLConnection to get the response, and put it in an NSData structure called webData. With _webData, I'm making this call:
[self.webView loadData:_webData
MIMEType:#"text/v-calendar"
textEncodingName:#"utf-8"
baseURL:[NSURL URLWithString:#"calshow://"]];
In my shouldStartLoadWithRequest: method, I'm telling any 'calshow://' urls to open the calendar, but I don't think this gets me anywhere, since I can't pass the NSData along with it. My main question right now is, can my UIWebView mimic how safari handles this ics data? If not, can I do anything useful with this NSData?
BEGIN:VCALENDAR\r\nPRODID:-//bobbin v0.1//NONSGML iCal
Writer//EN\r\nVERSION:2.0\r\nCALSCALE:GREGORIAN\r\nMETHOD:PUBLISH\r\nBEGIN:VEVENT...
UPDATE: I was able to get this working in a UIDocumentInteractionController, where it displays the dates and times exactly how safari would handle the data, however, there isn't an "Add All" button or an "Open in Calendar..." option. The UTI is correctly set to com.apple.ical.ics, but I'm not presented with any usable options in the view.
This link may offer a solution. Appears UIDocumentInteractionController works with .ics files, but I haven't verified.

Launching a different app to open file on server

The Apple Docs say that UIDocumentInteractionController "provides in-app support for managing user interactions with files in the local system". Is there a similar setup for viewing files on a server? I tried just sending the link to the file as the NSURL for interactionControllerWithURL:, but that didn't work. I guess the alternative would be to download the file, then open it once it has downloaded, then delete the file. That seems like a lot of extra coding work though, if there is an easier way that's already available.
Edit: I already know the name of the file I want to view/download, so I'm not really looking for the "file list" aspect of UIDocumentInteractionController. On the server, there are many Google Earth .kml files. The user isn't going to directly select which file to open from a list - I select the file to open programmatically based on actions taken by the user previously in the session.
As I understand it, presentOpenInMenuFromRect:inView:animated: will show a popover something like "Would you like to open the file 'myFile.kml' in Google Earth?". If the user selects 'Yes', the UIDocumentInteractionController launches Google Earth and opens myFile.kml. So I guess I'm not really looking for a file list viewer, just a way to trigger an "Open With" kinda functionality, where the file I'm opening exists on my server.
UIDocumentInteraction controller can't be used to view list of files present on server.
UIDocument interaction controller takes local file present in source application and shows list of applications that can open that file.Once use clicks on file then it is transferred to target app.
If you want to get file from server then you can use NSURLConnection class to download file form server and store it on device.
I think I figured this out. I don't need to use a UIDocumentInteractionController at all for what I'm looking for. I can simply
NSURL *url = [NSURL URLWithString:#"comgoogleearth://www.mysite.com/myfile.kml"];
BOOL canOpen = [[UIApplication sharedApplication] canOpenURL:url];
if (canOpen)
{
[[UIApplication sharedApplication] openURL:url];
}
else
{
NSLog (#"Open failed. Make sure Google Earth is installed and the URL is correct.");
}
This will launch Google Earth with my file just like I'm looking for.
FYI, I got the scheme for Google Earth from elpsk's answer to this question. It looks like a pretty comprehensive list of a lot of file types and the apps that open them. Just replace the comgoogleearth in my URL with the scheme for whatever app you are trying to open a file with.

Launching Safari using UIApplication:OpenURL not working

I've read several posts on here on how to launch Safari from within an app which all say to use UIApplication:OpenURL: However this is not working for me.
I have a .html page which has been downloaded and is stored in my application's sandbox.
I can launch this page in a UIWebView, but cannot launch it in, with the following code nothing happens.
NSURLRequest *requestObj = [NSURLRequest requestWithURL:firstPageFullPath];
[[UIApplication sharedApplication] openURL:[requestObj URL]];
The path is of the form file://..../page1.html, and as I mentioned, if I pass the requestObj to a UIWebView it will load successfully.
Any ideas why its not working, can Safari only be launched from an app with a non-local file?
Safari behaves pretty much like your own sandboxed app - i.e. it can't access files outside of its own sandbox. So it can't access the file you are referring it to with the file URL because that file resides in your app's sandbox, not Safari's. You should pass a remote URL to Safari - by putting your html on a web server somewhere. If this is not possible/practical for your app, then you'll need to continue using a UIWebView inside your app - as you have already found this is able to access the local html file. Implement any additional controls you need (forward, backward etc) to mimic the behaviour of Safari.
I'm going to guess that this is meant to happen for file URLs. If you use UIWebView, that browser instance uses your application's sandbox (e.g. The cookies available for that browser instance is independent with the Safari app's cookies). If you use Safari, then you're out of your sandbox, and Bad Thingsā„¢ can happen if Apple allows it to be used like a file-explorer.

Resources