I have defined the UTIs my app supports, and can drag them onto the Dock icon. I've also implemented -application:openFiles: and -application:openFile: in my app delegate. But when I get info on an item of a UTI I support, it doesn't show up in the list, and is grayed out when I browse to "other". I've pasted a sample UTI from my plist below. What could I be doing wrong? I especially want it to work with the built-in App Store integration.
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>cbz</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>CBZ</string>
<key>CFBundleTypeName</key>
<string>Comic Book Zip Archive</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSHandlerRank</key>
<string>Owner</string>
<key>LSItemContentTypes</key>
<array>
<string>com.abbey-code.cbz-archive</string>
</array>
</dict>
</array>
<key>UTExportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.zip-archive</string>
<string>public.data</string>
</array>
<key>UTTypeDescription</key>
<string>Comic Book Zip Archive</string>
<key>UTTypeIconFile</key>
<string>CBZ</string>
<key>UTTypeIdentifier</key>
<string>com.abbey-code.cbz-archive</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>cbz</string>
</array>
</dict>
</dict>
</array>
Update
I fired up a VM with no third party applications other than my own installed, and everything is working as expected there. I've rebuilt my LaunchServices database like so:
/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -kill -r -domain local -domain system -domain user ; killall Dock
And that made no difference. I then made a dump of the LaunchServices database using this command, with results for my app bundle below it. It looks reasonable to me, but I'm not sure what I'm looking for. Is it possible I'm experiencing some type of collision with the other apps on my system? If so, how would I resolve that?
/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -dump >>lsregister.txt
The dump:
bundle id: 61808
path: /Applications/AppName.app
name: AppName
category: public.app-category.entertainment
identifier: com.abbey-code.AppName (0x800183e0)
canonical id: com.abbey-code.appName (0x8001a08d)
version: 6433.0
mod date: 5/6/2014 22:54:46
reg date: 5/7/2014 9:04:25
type code: 'APPL'
creator code: '????'
sys version: 10.9
exec sdk ver: 10.9
exec os ver: 10.9
flags: relative-icon-path
item flags: container package application extension-hidden native-app x86_64
hi res: is-capabile is-explicit user-can-change
app nap: is-capabile
icon: Contents/Resources/AppIcon.icns
executable: Contents/MacOS/AppName
inode: 37029967
exec inode: 37030002
container id: 32
library: Contents/Library/
library items: QuickLook/AppNameQL.qlgenerator/
--------------------------------------------------------
type id: 46888
bindableKey: 3266
generation: 7459
uti: com.abbey-code.cbz-archive
description: Comic Book Zip Archive
flags: exported active trusted
icon: Contents/Resources/CBZ.icns
conforms to: public.zip-archive, public.data
tags: .cbz
--------------------------------------------------------
type id: 46932
bindableKey: 3267
generation: 7459
uti: com.abbey-code.cbr-archive
description: Comic Book RAR Archive
flags: exported active trusted
icon: Contents/Resources/CBR.icns
conforms to: public.archive, public.data
tags: .cbr
--------------------------------------------------------
claim id: 37936
bindableKey: 3268
generation: 7459
name: Comic Book Zip Archive
rank: Owner
roles: Editor
flags: relative-icon-path
icon: Contents/Resources/CBZ.icns
bindings: com.abbey-code.cbz-archive
--------------------------------------------------------
claim id: 37972
bindableKey: 3269
generation: 7459
name: Comic Book RAR Archive
rank: Owner
roles: Editor
flags: relative-icon-path
icon: Contents/Resources/CBR.icns
bindings: com.abbey-code.cbr-archive
--------------------------------------------------------
claim id: 38008
bindableKey: 3270
generation: 1
name: PDF Document
rank: Default
roles: Viewer
flags:
icon:
bindings: .pdf
--------------------------------------------------------
claim id: 38044
bindableKey: 3271
generation: 1
name: RAR Archive
rank: Default
roles: Viewer
flags:
icon:
bindings: .rar
--------------------------------------------------------
claim id: 38080
bindableKey: 3272
generation: 1
name: ZIP Archive
rank: Default
roles: Editor
flags:
icon:
bindings: .zip
--------------------------------------------------------
claim id: 38116
bindableKey: 3273
generation: 7459
name:
rank: Default
roles: QLGenerator
flags:
icon:
delegate: QuickLook/AppNameQL.qlgenerator/
bindings: com.abbey-code.cbz-archive, com.abbey-code.cbr-archive
You can set your application to be the one to be launched by default for a specific document type in code. I've found this to be necessary in some cases where setting the link in the info.plist was not sufficient. This would typically be in the +initialize method of you app controller:
//First Check if our app is the default application to open .cbz files
NSString *cbzUTI = (NSString *)CFBridgingRelease(UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension,
(CFStringRef)@"cbz",
NULL));
NSString *currentCbzApp = (NSString *)CFBridgingRelease(LSCopyDefaultRoleHandlerForContentType((__bridge CFStringRef)cbzUTI, kLSRolesAll));
if ([currentCbzApp caseInsensitiveCompare:@"com.abbey-code.AppName"] != NSOrderedSame) {
//If not, then first register it in Launch Services
LSRegisterURL((__bridge CFURLRef)[[NSBundle mainBundle] executableURL], YES);
//Second set it as the default handler for the file type
LSSetDefaultRoleHandlerForContentType((__bridge CFStringRef)cbzUTI, kLSRolesAll,(__bridge CFStringRef) [[NSBundle mainBundle] bundleIdentifier]);
}