How to Handle a File Sent with 'Open In...' from Another App to My Own iOS App

How to handle a file shared from another app to my own iOS app?

It looks like you followed the approach from this previous question only partially. In that case, the person had successfully implemented 2 of 3 parts of the solution for the custom URL scheme, so the answer only provided the 3rd part.

As https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app says:

To support a custom URL scheme:

  1. Define the format for your app’s URLs.
  2. Register your scheme so that the system directs appropriate URLs to your app.
  3. Handle the URLs that your app receives.

Their question was:

My app is being displayed in the available applications to which I can send the file to. My question is what happens after? When I choose to send it to my app it then switches over to my app and from there, I don't know how to receive the file and read it to extract its content.

So they had already done steps 1 and 2 (so, their app was being displayed properly in the available applications, etc.).

In your case, it sounds like you haven't done steps 1 and 2 yet?

The other possibility is (also from https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app) if you are using Scenes, note that there are additional entry points to your app.

If your app has opted into Scenes, and your app is not running, the system delivers the URL to the scene(:willConnectTo:options:) delegate method after launch, and to scene(:openURLContexts:) when your app opens a URL while running or suspended in memory.

Something like

func scene(_ scene: UIScene, 
willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions) {

// Determine who sent the URL.
if let urlContext = connectionOptions.urlContexts.first {

let sendingAppID = urlContext.options.sourceApplication
let url = urlContext.url
print("source application = \(sendingAppID ?? "Unknown")")
print("url = \(url)")

// Process the URL similarly to the UIApplicationDelegate example.
}

/*
*
*/
}

and as the Apple docs say, for the case the app is in the background, then implement something like

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>){
let url = URLContexts.first?.url
print("url = \(url)")

// Process the URL similarly to the UIApplicationDelegate example.
}

How to handle a file sent with 'Open in...' from another app to my own iOS app?

This is handled in your AppDelegate, more precisely, you get passed an URL to the document and then you handle it from there in optional function, e.g.:

func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
do {
let data = try Data(contentsOf: url)
// Do something with the file
} catch {
print("Unable to load data: \(error)")
}

return true
}

More info: https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623112-application

Handling files opened from outside sources in iOS/Swift

The only part that matters is this part:

// Add at end of application:didFinishLaunchingWithOptions
NSURL *url = (NSURL *)[launchOptions valueForKey:UIApplicationLaunchOptionsURLKey];
if (url != nil && [url isFileURL]) {
[rootController handleOpenURL:url];
}

// Add new method
-(BOOL) application:(UIApplication *)application handleOpenURL:(NSURL *)url {

RootViewController *rootController = (RootViewController *) [navigationController.viewControllers objectAtIndex:0];
if (url != nil && [url isFileURL]) {
[rootController handleOpenURL:url];
}
return YES;

}

The first code block is added to your AppDelegate's application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?)

The Swift equivalent is

if let options = launchOptions, let url = options[.url] as? URL, url.isFileURL {
// call some code to handle the URL
}

and this new function for the AppDelegate:

func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
if url.isFileURL {
// call some code to handle the URL
}
return true // if successful
}

All of the rest of the code in the article is a way to route the handling code to the root view controller. You could just handle it right in the AppDelegate or route it to another class if you wish.

Open file / content of other app into my own iOS app, when my app was in background

You can use below application delegate method

For IOS 9 and later

  • (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options

Below IOS 9

  • (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(nullable NSString *)sourceApplication
    annotation:(id)annotation

How to receive multiple files sent to my app from Files App

There doesn't seem to be a way to do this currently without directly accessing the folder that it's being stored in - which isn't really something I feel okay with.

In my app, we allow our share extension to accept multiple files at the same time and have it handled accordingly. You could probably try that while you wait for apple to give us something



Related Topics



Leave a reply



Submit