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

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).

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.

WARNING ITMS-90737: "Invalid Document Configuration [duplicate]

This question already has answers here:
App Store Connect Warns - Invalid Document Configuration
(7 answers)
Closed 4 years ago.
I got this error message when uploading my app to ItunesConnect today,
Invalid Document Configuration - Document Based Apps should support
either the Document Browser (UISupportsDocumentBrowser = YES) or
implement Open In Place (LSSupportsOpeningDocumentsInPlace = YES/NO).
Visit https://developer.apple.com/document-based-apps/ for more
information.
To Fix -
Open Info.plist file.
If you have UIDocumentInteractionController within your App use -
Add "UISupportsDocumentBrowser" select boolean YES
Otherwise -
Add "LSSupportsOpeningDocumentsInPlace" select boolean YES
Info.plist Code:
//if using - UIDocumentInteractionController
<key>UISupportsDocumentBrowser</key>
<true/>
//if not use -
<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>
From the Apple Developer Documentation
UISupportsDocumentBrowser
UISupportsDocumentBrowser (Boolean - iOS) Specifies that the app is a document-based app and uses the UIDocumentBrowserViewController class.
If this key is set to YES, the user can set the document browser’s default save location in Settings. Additionally, the local file provider grants access to all the documents in the app’s Documents directory. These documents appear in the Files app, and in a Document Browser. Users can open and edit these document in place.
This key is supported in iOS 11 and later.
UIDocumentInteractionController
Use this class to present an appropriate user interface for previewing, opening, copying, or printing a specified file. For example, an email program might use this class to allow the user to preview attachments and open them in other apps.
After presenting its user interface, a document interaction controller handles all interactions needed to support file preview and menu display.
You can also use the delegate to participate in interactions occurring within the presented interface. For example, the delegate is notified when a file is about to be handed off to another application for opening. For a complete description of the methods you can implement in your delegate, see UIDocumentInteractionControllerDelegate.
Reference Link
LSSupportsOpeningDocumentsInPlace
LSSupportsOpeningDocumentsInPlace (Boolean - iOS) When set to a value of YES, enables your app to open the original document from a file provider, rather than a copy of the document. The app can access documents from the system’s local file provider, the iCloud file provider, and any third-party File Provider extensions that support opening documents in place.
The URL for a document opened in place is security-scoped. For information about working with security-scoped URLs and bookmarks, read the overview in NSURL Class Reference and read Document Provider in App Extension Programming Guide.
Important: When opening a document in place, other processes can modify the document at any time. Therefore, you must coordinate your access to the document using either a UIDocument subclass or NSFilePresenter and NSFileCoordinator objects.
In iOS 11 and later, if both this key and the UIFileSharingEnabled key are YES, the local file provider grants access to all the documents in the app’s Documents directory. These documents appear in the Files app, and in a document browser. Users can open and edit these document in place.
Reference Link
Setting Up a Document Browser App Link

How to pass text to 3rd party app in iOS

My app generates some sort of text information.
User presses button like "Share" in my app and after that pops up a windows with a list of installed applications or only apps which can recieve string parameter. After that, user selects, for example, "Mail" app and then it is opened with the new email message and with a given text from my app. Or user selects Skype app and then it is opened with a given text.
How could those scenarios be implemented in iOS?
PS: I already saw similar behavior in Android app (via Intent extras).
UPDATE: I posted the answer below that works for me (via UIActivityViewController) exactly how I need.
There is no single answer that will work for all target apps. You need to research each app and see if it has a facility for receiving info from other apps.
A simple way to do this is to invoke an URL that targets the other app.
For mail, you could invoke a mailto:// URL that composes an email with the text in the desired field(s) (to, cc, bcc, subject, or body.)
If the app supports the iOS document model you may be able to pass it a document to open.
If the target app has a server then you may also be able to connect to the server and send data to it that way. Again, this is not a question you can ask in general. The answer will be different for each target app, and for some apps the answer will be "you can't, because it doesn't have any mechanism to receive data from an outside app."
Android is a different beast with different abilities than iOS. iOS is more of a "walled garden", with very limited access outside of your app.
I found the best solution for me is
- (IBAction)onShare:(id)sender {
NSString *textStr = self.textToShare.text;
NSArray *items = #[textStr];
UIActivityViewController *activity = [[UIActivityViewController alloc]
initWithActivityItems:items
applicationActivities:nil];
[self presentViewController:activity animated:YES completion:nil];
}
It does exactly what I need. It shows popup view with the list of apps which are able to receive text string. Then user can select any of them and controller sends text to it.

UIDocumentInteractionController handling ics files

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.

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