You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OS X应用开发:如何获取通过Custom URL Scheme唤起当前应用的源应用信息?

获取macOS应用中唤起当前应用的源应用信息

你提到的通过PID匹配的方案确实能解决问题,但确实有更优雅的方式——直接从触发的Apple Event中提取源应用的Bundle ID,不用遍历所有运行中的应用。

在macOS的Apple Event机制里,唤起你的应用的事件本身就携带了源应用的Bundle ID属性,对应的AE关键字是keySenderBundleIDAttr(定义在AEKeyword中)。你可以直接从事件对象中读取这个属性,一步到位获取Bundle ID,再通过Bundle ID快速定位到应用信息。

修改后的代码示例

class AppDelegate: NSObject, NSApplicationDelegate {
    func applicationWillFinishLaunching(_ notification: Notification) {
        NSAppleEventManager
            .shared()
            .setEventHandler(
                self,
                andSelector: #selector(handleURL(event:reply:)),
                forEventClass: AEEventClass(kInternetEventClass),
                andEventID: AEEventID(kAEGetURL)
            )
        NSLog("Debug: Handle Set")
    }

    @objc func handleURL(event: NSAppleEventDescriptor, reply: NSAppleEventDescriptor) {
        // 1. 获取传入的URL
        if let path = event.paramDescriptor(forKeyword: keyDirectObject)?.stringValue?.removingPercentEncoding {
            NSLog("Opened URL: \(path)")
        }
        
        // 2. 直接从Apple Event中获取源应用的Bundle ID
        if let bundleIDDescriptor = event.attributeDescriptor(forKeyword: AEKeyword(keySenderBundleIDAttr)),
           let sourceBundleID = bundleIDDescriptor.stringValue {
            NSLog("Source App Bundle ID: \(sourceBundleID)")
            
            // 3. (可选)通过Bundle ID获取源应用的本地化名称
            if let sourceApp = NSWorkspace.shared.runningApplications.first(where: { $0.bundleIdentifier == sourceBundleID }) {
                if let appName = sourceApp.localizedName {
                    NSLog("Source App Name: \(appName)")
                }
            }
        }
    }
}

为什么这个方案更优?

  • 更直接:不需要先获取PID再遍历所有运行应用,直接从事件中读取Bundle ID,减少了中间步骤
  • 性能更好:避免了遍历runningApplications的开销,尤其是当系统运行大量应用时
  • 更可靠:直接依赖系统传递的属性,比PID匹配的方式更稳定(PID可能会被复用,但Bundle ID是应用的唯一标识)

如果只需要Bundle ID,那么步骤2就足够了;如果需要应用名称,通过Bundle ID查找的方式也比遍历所有应用高效得多——因为runningApplications.first(where:)会在找到匹配项后立即停止遍历。

内容的提问来源于stack exchange,提问作者Charles

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 09:32:45