4

I'm trying to allow my app to open multiple files at the same time - e.g. select multiple with files app, then press "open in [my app]". When I try this, sure enough UIApplicationDelegate openURL fires in my app, but I only get one URL. Is there a way of getting all the files, rather than just one of them?

mazbox
  • 613
  • 1
  • 5
  • 7

1 Answers1

0

Your observation is correct, with openURL call you will get only one file. The Alternative solution to this problem is to implement an action extension.

  1. In action extension, you can iterate all the file items,
  2. create a copy of files in your application's shared space.
  3. And create a string with comma-separated file URLs
  4. and send this string object (base64 encoded or any other encrypted format) to your application using a custom URL for your application. For ex: app://filesaction/<encoded/encrypted_value>
  5. In your application you can decode/decrypt the string received (the last component of URL) from the action extension. and use a list of files as your own wish.

Official open URL calls are not allowed from action extension, but you can iterate the responder chain and can open your application with that:

 let selectorOpenURL = sel_registerName("openURL:")
      while (responder != nil){
            if responder?.responds(to: selectorOpenURL) == true{
             responder?.perform(selectorOpenURL, with: url)
            }
        responder = responder!.next
        }

Edit:

answers to points raised in comments :

  1. OpenURL trick might break in the future: if you search for this issue, you will find so many applications are using the same. not using any private API, chance are were less
  2. Manually enabled part I am not sure, I guess that happens only when there are a lot of action extensions available. When we supported action extension didn't face a manual enabling case.
  3. Google Drive and other apps you mentioned are using share extension to achieve the same, you can also use share extension. If you observe these app doesn't switch to the main app, presents extension UI on the host app, and do the task without switching to the main app.
  4. Basically by Apple's guideline share extensions and action extensions should not open the main app. But using open URL trick so many app doing this.
  5. last question valid, in that case instead of you should go for a share extension if you enable a share extension for your application. Your application will not appear (from iOS 14 onwards, earlier there used to be both: app share extension and application openURL (copy to app)) for openURL. Basically share extension will trigger from your application icon in the share sheet.

Summary: You can avoid the OpenURL tricky part by implementing a share extension and that will resolve the issue of users using OpenURL instead of action extension. This may be though to achieve if you are using a lot of memory since share extension and action extension have limited memory access. In that case, you may want to switch to your main app(OpenURL trick).

Manish Punia
  • 747
  • 4
  • 9
  • Thanks. According to Apple's DTS, "there is no supported way to achieve the desired functionality given the currently shipping system configurations". I believe that openURL trick shows that using Action Extensions that way is not officially supported by Apple, and may break in a future update. – Thomas Nov 25 '20 at 15:49
  • Action Extensions have to be manually enabled, and appear in the list below the list of apps, whereas Google Drive, Fastmail, and many other apps appear to be accepting multiple files when selected from the app list, above the Action Extensions list. Could they be doing that differently, or is it possible to trigger an action extension directly from the app list? I fear that if I use an Action Extension, users will try sending files by selecting the app in the app list, and never realize they have to enable the action extension and use it instead in order to be able to send multiple files. – Thomas Nov 25 '20 at 15:50