Swift:我可以获取非 运行 的应用程序的信息吗?

Swift: Can I get information for an application which is not running?

我正在编写一个存储有关其他应用程序数据的应用程序。我可以很容易地找到当前最前面的应用程序及其信息:

let frontApp = NSWorkspace.shared.frontmostApplication!

从那里我可以得到:

let currentAppName = currentApp.localizedName ?? "Dunno"
let currentAppIcon = currentApp.icon

如果应用程序不在前台,我知道我可以遍历其他 运行 应用程序:

let apps = NSWorkspace.shared.runningApplications
for app in apps as [NSRunningApplication] {
    print(app.localizedName ?? "whatever")
    print(app.bundleIdentifier ?? "bundle")
}

我想获得关于当前不属于 运行 但我有捆绑包标识符的应用程序的相同信息。我怎样才能得到这个?

首先,使用

获取应用程序的包
let bundleURL = NSWorkspace.shared.urlForApplication(withBundleIdentifier: someBundleID)!
let bundle = Bundle(url: bundleURL)!

获得捆绑包后,您可以从 NSRunningApplication:

中获得大部分内容
  • bundleIdentifier你已经知道了。
  • bundleURL 你刚刚用上面的代码得到了。
  • executableArchitecture 现在是 bundle.executableArchitectures,带有复数形式。因为它不是 运行ning,所以您会得到它可以 运行 的所有架构,而不是 运行ning 的特定架构。
  • executableURL 你可以用 bundle.executableURL,没问题。
  • launchDateisFinishedLaunchingprocessIdentifierownsMenuBar 是无意义的,因为应用程序不是 运行ning.

现在我们只剩下 iconlocalizedName。我提出的获取这些方法的方法不太可靠。要获得 icon,请执行

NSWorkspace.shared.icon(forFile: bundleURL.path)

我确信这至少在 99% 的情况下会产生与 NSRunningApplication.icon 相同的结果,但我不确定是否存在边缘情况...

得到localizedName比较不靠谱。有2种方法,哪一种都不好。选择最适合您的目的

  • FileManager.default.displayName(atPath: bundleURL.path) 这为您提供本地化名称,但如果用户重命名应用程序,它将 return 新名称,而不是包名称

  • 从捆绑包的 localizedInfoDictionary 中获取 CFBundleDisplayName,返回到 CFBundleNameinfoDictionary。由于某种原因,这没有给出本地化名称,即使我说 localizedInfoDictionary.

    let infoDict = (bundle.localizedInfoDictionary ?? bundle.infoDictionary)
    let localizedName = infoDict?["CFBundleDisplayName"] ?? infoDict?["CFBundleName"]