UIDocumentInteractionController handling ics files - ios

I've managed to open an ics file stored locally, and the UIDocumentInteractionController recognizes it the UTI as com.apple.ical.ics (which is expected). The data displays as I was hoping, for the most part:
I was under the impression from the docs that UIDocumentInteractionController would automatically recognize this ics file type and give some calendar-related options, however, there doesn't seem to be any way for me to add these events to my calendar from this view. Under the "Open in" menu, I see mail and dropbox as options, but not Calendar. If I email it to myself, I then can add the events from the mail app. Am I missing something with how this view works? Mobile Safari handles ics files in a similar way, except there will be an "Add all" button in the title bar. That's exactly how I thought this would behave. I'd prefer not to use EventKit at this point, since I'd just like it to mimic how safari handles the file.

Related

How do I determine that a link is a calendar event from an IOS App and then add it to Calendar?

I have written an iPhone App that looks at a webpage. (I have authorized the App to access Calendar.) One of the links is a calendar link. When I look at that link with Safari, I get a message.
https://www.dropbox.com/s/opzhxcrg8ye2z4v/Screen%20Shot%202018-11-23%20at%201.17.15%20PM.png?dl=0
"The website is trying to show you a calendar invite. Do you want to allow it ...". I can then add it to my calendar. However, when I open that identical link inside my app, my app does not recognize it is a calendar link and then I get options to either Open, Add to Read List, copy ...".
https://www.dropbox.com/s/wd7n8n9bz764wih/Screenshot%202018-11-23%2013.20.53.png?dl=0
My question is how to get my App to recognize that a link is a calendar link?
One determines what should be in the file by the suffix and the MIME content type.
For icalendars, the suffix is .ics and the MIME content type is text/calendar. If a link does not have .ics suffix your app can ignore it, if it has a .ics, then it should check the header for the mime-type.
What is a MIME type?
https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Complete_list_of_MIME_types
What a browser or device actually does with the file depends on what the user has set in the settings. EG: a .pdf will topen in the way that the user has told the browser to open .pdf's - either in browser or adobe reader.
EG in windows for development purposes, I have specified that calendar links (links with suffix .ics) should be opened in my editor rather than my calendar.

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.

How to write URL to force mobile Safari to display "Open In..." dialog for Dropbox links

I have an MP3 in Dropbox that I am able to force browsers to download rather than handle natively, with the exception of Safari on iOS. In this case, a straight link on my website to the file opens the Dropbox mobile site with the file showing this:
http://imgur.com/mePjw0m
The Download button in the center just opens the MP3 via QuickTime within Safari, while the button on the top right of the page opens another screen that offers "Direct Download" and "Add to my Dropbox". "Direct Download" plays the MP3 within Safari, while "Add to my Dropbox" opens a sign-in page. This is not only inconvenient (why bother havign native apps if Safari won't offer links to them?) but also frustrating for the end user. Not everyone uses Dropbox, and of those who do, most probably aren't inclined to log in via Safari when they already have the app.
What I'm looking for is some way to force mobile Safari to show the "Open In..." menu (best solution) or at the very least, for Dropbox users, to show the "Open in Dropbox" button that appears when Safari can't handle the file natively. The Dropbox app as well as other cloud storage apps are registered in iOS to handle MP3s. When users open PDFs in Safari they are given the choice to open in other apps as well, so there should be no reason that Safari can't do the same with MP3s.
Safari on iOS will not show an "Open in" option for mp3 files, so what you are asking may not be possible.
If you want to load the file directly (bypassing the Dropbox webpage), in the Dropbox link change www to dl. On top of that, normally if you add ?dl=1 to the end of the url it will force it to download. However, you will see that in iOS Safari it behaves the same way as if you just changed the "www" and does not allow you to send it to another app.

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.

Resources