Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FB16362713: NSWorkspace.shared.urlsForApplications(toOpen: .html) is missing some apps #602

Open
sindresorhus opened this issue Jan 19, 2025 · 0 comments

Comments

@sindresorhus
Copy link
Member

  • Date: 2025-01-20
  • Resolution: Open
  • Area: AppKit
  • OS: macOS 15.2
  • Type: Incorrect/Unexpected Behavior

Description

For example, the Zen Browser app (https://zen-browser.app) is able (registered to handle) to open HTML documents, but does not show up in the list. Same with Firefox. However, they do show up with LSCopyAllRoleHandlersForContentType(kUTTypeHTML, .viewer)?.takeRetainedValue() as? [String] ?? []. The former is documented as a replacement for the latter, but it seems they use different logic. I initially thought there was something wrong with my system, but I also got a report from a user on one of my apps that uses NSWorkspace.shared.urlsForApplications(toOpen: .html) that said Zen Browser was missing, so there is definitely something going on.

I have tried both in a sanboxed and unsandboxed app.

The missing apps live in /Applications, but same result if they are in ~/Applications. I have also tried turning Spotlight off and on again. And I have tried resetting lsregister. Restarting computer. Nothing helped.

The "default browser" setting in System Settings does include Zen Browser, so I have a feeling it is using the older API.

NSWorkspace.shared.urlsForApplications(toOpen: "https:") also does not return Zen Browser, even though the app registers to handle https and http schemes.


I have written a simple script to compare the output of these methods:

func compareHTMLHandlers() {
	// Get URLs from NSWorkspace
	let workspaceURLs = NSWorkspace.shared.urlsForApplications(toOpen: .html)
	let workspaceHandlers = Set(workspaceURLs.compactMap { url -> String? in
		Bundle(url: url)?.bundleIdentifier
	})

	// Get handlers from Launch Services
	let lsHandlers = Set(LSCopyAllRoleHandlersForContentType(kUTTypeHTML, .viewer)?.takeRetainedValue() as? [String] ?? [])

	// Find differences
	let onlyInWorkspace = workspaceHandlers.subtracting(lsHandlers)
	let onlyInLaunchServices = lsHandlers.subtracting(workspaceHandlers)

	// Print results
	print("Only in NSWorkspace:")
	for bundleID in onlyInWorkspace.sorted() {
		if let appURL = NSWorkspace.shared.urlForApplication(withBundleIdentifier: bundleID) {
			print("- \(bundleID) (\(appURL.lastPathComponent))")
		} else {
			print("- \(bundleID)")
		}
	}

	print("\nOnly in Launch Services:")
	for bundleID in onlyInLaunchServices.sorted() {
		if let appURL = NSWorkspace.shared.urlForApplication(withBundleIdentifier: bundleID) {
			print("- \(bundleID) (\(appURL.lastPathComponent))")
		} else {
			print("- \(bundleID)")
		}
	}
}

compareHTMLHandlers()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant