Importing Unknown UTTypes at Runtime

Hello everyone!

I am running into an issue trying to use UTType with identifiers that are not known until runtime.

For example, running this code

import UniformTypeIdentifiers
let type = UTType(importedAs: "com.example.fileformat")

creates a console warning

[Type Declaration Issues] Type "com.example.fileformat" was expected to be declared and imported in the Info.plist of Debug, but it was not found.

and a Xcode runtime warning

However, the UTType object is initialized and can be used.

identifier: com.example.fileformat
isPublic:   false
isDynamic:  false
isDeclared: true

Normally, this would be a simple "just add it to Info.plist", but with my program it is impossible to know all possible types at build time (content from NSPasteboard).

Does anyone know if this is a warning that can be ignored, or is this undefined behavior?

Thanks!

Hi there! The runtime issue you're seeing is real and is describing a bug in your application.

I recommend you take a moment and review the video we released last year about the Uniform Type Identifiers technology and framework. In that video, we explain how to use UTType(importedAs:) and why you're getting this runtime issue. Also there's a kitty! 😺

In this case, you're getting a warning because the type you want to use is not declared in your Info.plist file as an imported type. Importing a type, and by extension using UTType(importedAs:), is a way for your app to guarantee that a type exists and that your app knows about it. Importing rather than exporting is a way for your app to say "this isn't my type, I'm just borrowing it. Another app might know better than I do." The video goes into more detail about what importing/exporting types means for your app, and when it is appropriate to do one, the other, or neither.

UTType(importedAs:) always returns a non-nil value because, as part of the API contract, you promised it would exist. Since the type does not exist, the system returns a placeholder object without any metadata other than the type identifier you provided. This UTType value has no associated filesystem representations (path extensions, etc.), no localized name or icon to present to users, and no inheritance from other types.

A reminder as well that the "com.example.*" identifier namespace is reserved for examples and documentation—make sure to change the type identifier you're using to something in your domain before you deploy your app to customers. 😃


Edit: I almost missed the NSPasteboard context here. Too early, need coffee. ☕️

If you want to get a UTType value for an arbitrary type identifier of unknown provenance, use UTType("com.example.identifier"). This is a failable initializer—if it returns nil, then there is no type known to the system with that identifier. All valid UTType instances must be declared by an app, be declared by the system, or be dynamically generated by the system.

if let type = UTType(identifierFromPasteboard) {
  print("This type's name is \(type.localizedDescription).")
  if type.conforms(to: .image) {
    print("It might even be a picture of a kitty!")
  } else {
    print("It isn't a picture of a kitty. 😿")
  }
}
Importing Unknown UTTypes at Runtime
 
 
Q