4

In my iOS app I am opening a UIDocumentPickerViewController to import .sty files (MIDI styles). For this I have declared a custom UTI in Imported UTIs and in Document Types.

The problem is that on my customer’s iPad Air 2, these files appear greyed out in the dialog so he cannot import them. On my iPad Air 2 they are not greyed out, and I can import them successfully. We can both see this when using iCloud Drive and Dropbox as file providers.

What could be different on our devices? My customer installs the app as an internal tester via TestFlight.

Also, are file extensions in the Import UTIs case-sensitive? I would not think so.

Then I wonder if I should add a document type icon or not. According to the reference the icon is not required.

iCloud Documents is enabled: enter image description here

Here is the code that presents the UIDocumentPickerViewController:

let utis = [String](PlaylistItem.utiToType.keys)
let viewController = UIDocumentPickerViewController(documentTypes: utis, in: .import)
viewController.delegate = self
viewController.modalPresentationStyle = .formSheet
if #available(iOS 11, *) {
    viewController.allowsMultipleSelection = true
}
self.present(viewController, animated: AppDelegate.isAnimationsEnabled, completion: nil)

with this definition of UTIs in the PlaylistItem class:

enum FileType: Int {
    case other
    case mid
    case mp3
    case m4a
    case aiff // AIFF audio recording
    case wave
    case turboMidi // purchased MIDI file
    case style
}

static let kUTTypeStyleYamaha = "com.turboreini.style" // matches document types in Info.plist

static let utiToType: [String: FileType] = [
    kUTTypeMPEG4Audio as String: .m4a,
    kUTTypeMP3 as String: .mp3,
    kUTTypeMIDIAudio as String: .mid,
    PlaylistItem.kUTTypeStyleYamaha: .style
]

This is the Document Type as captured from Xcode 9: enter image description here

… and the Imported UTIs section: enter image description here

Note that I picked an arbitrary identifier for style files because I couldn’t find an official one on the internet.

This issue drives me crazy. I cannot find anything wrong.

I wonder if it depends on other installed apps.

In addition to importing .sty files, the app also creates its own custom files with their own extension. For this I have defined an Exported UTI. It works fine, no files are greyed out. But the solution to importing .sty files should not be to move the entry from Imported to Exported UTIs. My app is only a “viewer” to .sty files.

Any ideas on this case would be much appreciated.

bio
  • 669
  • 4
  • 14
  • 1
    .sty is also used by other file formats such as LaTeX. Might jour customer have an app which declares .sty as another UTI? – Thomas Deniau Aug 25 '18 at 21:13
  • Thanks for the idea. Indeed we found out that another app interfered by declaring (probably) another UTI for .sty files, though it was also a musical app that could load style files. – bio Aug 27 '18 at 09:54

1 Answers1

4

It turned out that on my customer’s iPad another app was installed that presumably also had its own UTI for the .sty extension. Once I installed it on my iPad I could reproduce the problem.

Unfortunately I was not able yet to peek into that app’s Info.plist to confirm.

However, thanks to Cocoanetics I found an API that allowed me to query the system:

let pathExt = "sty"
if let utiArray = UTTypeCreateAllIdentifiersForTag(kUTTagClassFilenameExtension, pathExt as NSString, nil)?.takeRetainedValue() as? [String] {
    print("Have UTIs for .\(pathExt):")
    for uti in utiArray {
        if let dict = UTTypeCopyDeclaration(uti as NSString)?.takeUnretainedValue() as? [String: Any] {
            print("\(uti) = \(dict)")
        }
    }
}

This code would show me the declared UTIs from all the apps installed on my iPad, based on the file extension. And indeed the other app showed up. But I still could not see if it was declared as an exported or imported UTI.

The workaround is to uninstall the conflicting app.

To me this is a flaw in the UTI system. I will try and contact the makers of .sty files (MIDI styles, not LaTeX files), to ask them for a proper UTI which all developers should conform to.

It seems a global registry of UTIs is needed. Apple has already created a collection but only the most popular types are covered.

bio
  • 669
  • 4
  • 14
  • 1
    The Cocanetics link is a great resource. That has several functions (in Objective C, fortunately for me) for inspecting existing UTI definitions and which apps are creating them. I'm assuming that copying a proprietary definition from the original developer's app is a safe bet. For file types that don't have a proprietary or standardized definition, I found that I had to use a UTI it conformed to -- for example, I'm using public.text to target .chordpro files. – arlomedia Aug 29 '18 at 19:25