3

Just to give some context, there is an iOS app I'm building (in Xamarin) that requires the ability to fetch files (in an automatic way without having the user to navigate to the files and select them manually) that are stored on External Storage Devices (USB Sticks), and are connected (paired) to an iPhone/iPad.

Users connect a lighting cable to the iOS Devices, and plug their USB Sticks into this lighting cable. Here is an example of the cable that end users use to pair the USB Sticks with their iPhone/iPad, and the app then auto fetches these files from the USB Storage Devices.

enter image description here

The app then performs 2 functions:

  1. It listens to notifications, for when a usb stick is paired with the iOS Device.
  2. When it receives this notification, it then proceeds with querying the files on the USB Stick, and reads and processes the files. The app reads these files automatically and the user does not need to manually select these files

I've tried using External Accessory Framework, however that's only suitable for devices that you register with the MFi program. https://developer.apple.com/documentation/externalaccessory

Notifications Center never seems to work (the Notifications that handle when a Device gets Connected and Disconnected, the delegates never get called), and I've tried using the Microsoft Helpers.

https://learn.microsoft.com/en-us/dotnet/api/externalaccessory.eaaccessorymanager.notifications.observedidconnect?view=xamarin-ios-sdk-12

I've also tried some 3rd party libraries, but haven't found anything useful.

It doesn't look Apple has any Api Available to auto query and read the files, without having to use a DocumentPickerController. I know this is because of the App Sandbox, and I cannot directly access the Removable Storage Devices.

Now for my questions:

  1. Are there any 3rd party libraries anybody can recommend, that can help achieve most of the heavy lifting for this task? I'd prefer a library that's compatible with Xamarin, however if it's a native library (Swift or Objective-C Library, Cocoapods) I'm sure there is a binding I can use on nuget.
  2. Does anybody have any snippets, or documentation, or can point me in the right direction here (Please feel free to post Swift, or Objective-c solutions here if you like)? Where should I look, which Apple Framework (iOS SDK) is most suitable to deal with this situation. And to summarise, is what I'm asking for at all possible on iOS, without having to jailbreak, or get around the App Sandbox?

Update

So I've tried the solution that @Saamer suggested: Detect if USB is connected to iPhone device

Here is an example I wrote just to verify if the callback gets invoked, and the app can detect if a usb is plugged in.

CFNotificationCenter.Darwin.AddObserver("com.apple.mobile.lockdown.host_attached", null, (e, s) =>
        {
            MainThread.BeginInvokeOnMainThread(async () =>
            {
                var picker = await Xamarin.Essentials.FilePicker.PickAsync();
            });
    }, CFNotificationSuspensionBehavior.DeliverImmediately);

A file picker should immediately get invoked, and open up, once I plug the USB in, however this doesn't happen.

I'm happy for a solution right now which opens up a file picker, when the user plugs in a USB Device, and navigates to the root directory to start off with. So when the File Picker opens up the user should see this. Then they can select the files they want to transfer into the app.

enter image description here

Saamer
  • 4,687
  • 1
  • 13
  • 55
Dan Gerchcovich
  • 168
  • 5
  • 12
  • "automatically reading files off external storage" sounds like a security risk, and the type of thing Apple usually prohibits. – Jason Jan 23 '22 at 16:59
  • iOS apps cannot access external storage devices directly. User interaction is required via the document picker. – Paulw11 Jan 23 '22 at 18:29
  • 1
    @Jason I'm planning to only release this application to testflight. So there's not going to be any review team involved. – Dan Gerchcovich Jan 23 '22 at 22:39
  • what does "review team" have to do with anything? The OS does not allow it. – Jason Jan 23 '22 at 23:15
  • 1
    @Jason, by "review team" I mean, that if I can get around the OS restrictions, then at least I can publish it to the end users, without having a human review team blocking the release – Dan Gerchcovich Jan 23 '22 at 23:27
  • @dan does the app need to be distributed through TestFlight or the App Store? Because if not you can use IOKit and distribute through AppCenter, as long as you have the UDIDs of all the devices you need the app installed on (up to 100?) – Saamer Jan 30 '22 at 17:40
  • 2
    @Saamer I have to distribute the app via testflight or the app store – Dan Gerchcovich Jan 30 '22 at 22:52

1 Answers1

1
  1. I thought you needed to jailbreak but it seems unlikely, a solution is possible for <iOS 12

According to the Apple Docs

You can use the Files app and other supported apps to access files stored on external devices, such as USB drives and SD cards, connected to your iPhone.

  1. Essentially you have to make your a "supported app". I have downloaded a free app called "Clockology" that I recommend downloading and playing with, which allows users to see data within the app as you can see below: Clockology app screenshots

You generally use UIDocumentPickerViewController along with the right uttype to get the files from the Files apps or iCloud Drive, and you require activating the Key-value storage and iCloud Documents from iCloud entitlements capability. There's a lot of tutorials on UIDocumentPickerViewController usage, but you specifically want the capabilities that became available from iOS 13 onwards

Entitlements

This video from WWDC is the best example of getting to where you want. I also didn't find any 3rd party libraries that can help with this

——————-

Edit: If the app does not need to be distributed through TestFlight or the App Store, you can use IOKit and distribute through AppCenter, as long as you have the UDIDs of all the devices you need the app installed on (up to 100?)

Saamer
  • 4,687
  • 1
  • 13
  • 55
  • Thanks for taking the time to answer. So I've tried your solution with https://stackoverflow.com/questions/46883205/detect-if-usb-is-connected-to-iphone-device/46976113#46976113. But this is not compatible for iOS 12 and above. The callback never gets called – Dan Gerchcovich Jan 28 '22 at 05:01
  • Ah yes I did some more research @dangerchcovich and I updated my answer based on it. – Saamer Jan 30 '22 at 01:27
  • 1
    Thanks for your help. I awarded you the bounty. – Dan Gerchcovich Feb 01 '22 at 02:57
  • I appreciate it buddy, I know it’s not exactly what you were hoping for. Please mark as the answer as well – Saamer Feb 02 '22 at 01:58