Is there a way to preserve capitalisation of original picked file while using UIDocumentPickerViewController?

182 Views Asked by At

The iOS 14 SwiftUI app I am developing has two ways of importing the audio files it plays: users can open a UIDocumentPickerViewController and select an audio file accessible on their phone (for example, one in their Dropbox), or they can transfer an audio file to the app via AirDrop.

I am running the app on my phone, not on the simulator.

I have a file in my Dropbox whose filename appears as "09 The Chant of the Tuxedos.mp3". When I open my app's file picker, the filename appears with this capitalisation within Dropbox. When I select it, however, this filename appears to lose its capitalisation by the time my document picker coordinator's didPickDocumentsAt routine gets hold of the URL.

   class Coordinator: NSObject, UIDocumentPickerDelegate, UINavigationControllerDelegate {
    var parent: FilePicker
    
    init(_ parent: FilePicker){
        self.parent = parent
    }
        
        func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {

            guard let url = urls.first, url.startAccessingSecurityScopedResource() else {
                return
            }
            parent.soundURL = url
...

invoking po url at this point yields:

file:///private/var/mobile/Containers/Shared/AppGroup/6032207B-36E4-464C-99F5-8448D1E62174/File%20Provider%20Storage/125859280/local-storage/L21wMy8wOSB0aGUgY2hhbnQgb2YgdGhlIHR1eGVkb3MubXAz/09%20the%20chant%20of%20the%20tuxedos.mp3
- _url : file:///private/var/mobile/Containers/Shared/AppGroup/6032207B-36E4-464C-99F5-8448D1E62174/File%20Provider%20Storage/125859280/local-storage/L21wMy8wOSB0aGUgY2hhbnQgb2YgdGhlIHR1eGVkb3MubXAz/09%20the%20chant%20of%20the%20tuxedos.mp3

On the other hand, if I AirDrop the same DropBox file to my app from my computer, the filename capitalisation is preserved.

In SceneDelegate.swift I have:

func scene(
  _ scene: UIScene,
  openURLContexts URLContexts: Set<UIOpenURLContext>
) {

  guard let urlContext = URLContexts.first else {
    return
  }
  let fm = FileManager.default
...

po urlContext at this point yields

<UIOpenURLContext: 0x2830c5000; URL: file:///private/var/mobile/Containers/Data/Application/D7D6E213-C661-4960-A31D-310B31615B3E/Documents/Inbox/09%20The%20Chant%20Of%20The%20Tuxedos.mp3; options: <UISceneOpenURLOptions: 0x283e953e0; sourceApp: (null); annotation: (null); openInPlace: NO>>

The following are the makeCoordinator() and makeUIViewController functions for my document picker:

func makeCoordinator() -> Coordinator {
     return Coordinator(self)
 }

func makeUIViewController(context: Context) -> UIDocumentPickerViewController {
    
    let supportedTypes: [UTType] = [UTType.audio]
    let picker = UIDocumentPickerViewController(forOpeningContentTypes: supportedTypes, asCopy: false)
    picker.shouldShowFileExtensions = true          // Sigh - quite pointless, it turns out
    picker.delegate = context.coordinator
    picker.allowsMultipleSelection = false
    return picker
}

Is there any way I can pick an audio file via UIDocumentPickerViewController (or by any other means) that will preserve the original file capitalisation?

2

There are 2 best solutions below

0
On BEST ANSWER

If you run the same code on a file that lives elsewhere, like On My Phone, you won’t have this issue. Dropbox itself is causing the problem.

I have read that you can learn the original capitalization of the filename using the Dropbox API and consulting the file metadata, but I don't believe there's a way to do that in your situation.

0
On

if ios target above ios 14 then try to use .fileImporter presentation modifier

.fileImporter(isPresented: $showDocumentPicker,
                      allowedContentTypes: [.audio],
                      allowsMultipleSelection: true)
        { result in
            // processing results Result<[URL], Error>
        }