LSGetApplicationForInfo is gone, but its replacements do not provide the same functionality

Originator:jtbandes
Number:rdar://21698360 Date Originated:7/6/2015
Status:Open Resolved:
Product:OS X SDK Product Version:10.10.4 (14E46)
Classification: Reproducible:
 
Summary:
LSGetApplicationForInfo is deprecated in 10.10 and missing from headers in the 10.11 SDK. The deprecation notice says "Use LSCopyDefaultApplicationURLForContentType instead."

However, the replacement APIs (and all other LaunchServices APIs) return different results when determining the application for a given content type.

Steps to Reproduce:
1. Obtain a Keynote .key presentation and a .m4v video.
2. Download VLC and make sure it's your default player for m4v files.
3. Run the following code in a Swift playground (Xcode 6):

import AppKit

func getApplicationForInfo(inType: Int, inCreator: Int, inExtension: String, inRoleMask: LSRolesMask) -> NSURL?
{
    var val: Unmanaged<CFURL>?
    withUnsafeMutablePointer(&val) { LSGetApplicationForInfo(OSType(inType), OSType(inCreator), inExtension, inRoleMask, nil, $0) }
    return val?.takeRetainedValue()
}

NSWorkspace.sharedWorkspace().URLForApplicationToOpenURL(NSURL(fileURLWithPath: "/path/to/existing/file.key")!) // VLC

getApplicationForInfo(kLSUnknownType, kLSUnknownCreator, "key", kLSRolesAll) // Keynote
LSCopyDefaultRoleHandlerForContentType(   "com.apple.iwork.keynote.key", kLSRolesAll)?.takeRetainedValue() // Keynote
LSCopyDefaultApplicationURLForContentType("com.apple.iwork.keynote.key", kLSRolesAll, nil)?.takeRetainedValue() // Keynote

getApplicationForInfo(kLSUnknownType, kLSUnknownCreator, "key", kLSRolesViewer) // Preview
LSCopyDefaultRoleHandlerForContentType(   "com.apple.iwork.keynote.key", kLSRolesViewer)?.takeRetainedValue() // Preview
LSCopyDefaultApplicationURLForContentType("com.apple.iwork.keynote.key", kLSRolesViewer, nil)?.takeRetainedValue() // Preview


NSWorkspace.sharedWorkspace().URLForApplicationToOpenURL(NSURL(fileURLWithPath: "/path/to/existing/file.m4v")!) // VLC

getApplicationForInfo(kLSUnknownType, kLSUnknownCreator, "m4v", kLSRolesAll) // VLC
LSCopyDefaultRoleHandlerForContentType(   "com.apple.m4v-video", kLSRolesAll)?.takeRetainedValue() // com.apple.system-library !??!
LSCopyDefaultApplicationURLForContentType("com.apple.m4v-video", kLSRolesAll, nil)?.takeRetainedValue() // CoreMedia.mdimporter !??!

getApplicationForInfo(kLSUnknownType, kLSUnknownCreator, "m4v", kLSRolesViewer) // VLC
LSCopyDefaultRoleHandlerForContentType(   "com.apple.m4v-video", kLSRolesViewer)?.takeRetainedValue() // nil !??!
LSCopyDefaultApplicationURLForContentType("com.apple.m4v-video", kLSRolesViewer, nil)?.takeRetainedValue() // VLC

Expected Results:
Goal: determine which application would be used to open a given file type, if the user double-clicked it from Finder.

LSGetApplicationForInfo does this, but its replacements do not. The desired output for "key" or "com.apple.iwork.keynote.key" would be Keynote.app itself, and for "m4v" or "com.apple.m4v-video" we would expect to get VLC.app.

Actual Results:
LSCopyDefaultApplicationURLForContentType :: com.apple.m4v-video :: kLSRolesAll :: returns /System/Library/Spotlight/CoreMedia.mdimporter?!
LSCopyDefaultApplicationURLForContentType :: com.apple.m4v-video :: kLSRolesViewer :: returns VLC as expected

So I thought maybe kLSRolesViewer is the correct value to use, however,

LSCopyDefaultApplicationURLForContentType :: com.apple.iwork.keynote.key :: kLSRolesAll :: returns Keynote.app as expected
LSCopyDefaultApplicationURLForContentType :: com.apple.iwork.keynote.key :: kLSRolesViewer :: returns Preview.app?!

Note that LSCopyDefaultRoleHandlerForContentType also returns incorrect values as seen in the playground. It seems there is no alternative to LSGetApplicationForInfo.

Comments


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!