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

如何在macOS任意应用中通过全局快捷键获取选中文本?

可靠读取任意应用选中文本的方案

你的剪贴板方案存在局限性:部分应用可能拦截Command+C快捷键,或者延迟设置不当导致数据读取失败,且剪贴板操作可能干扰用户原有数据。以下是两种更可靠的实现方式:

一、改进版AppleScript:优先调用应用原生脚本接口

针对支持AppleScript的应用(如Safari、Chrome、Word),直接调用其selected text相关属性,避免依赖剪贴板;对不支持的应用,再 fallback 到剪贴板方法。

改进后的AppleScript代码

set frontApp to path to frontmost application as text
set appName to name of application frontApp

try
    tell application appName
        if it is application "Safari" then
            set selectedText to selected text of front document
        else if it is application "Google Chrome" then
            set selectedText to execute front window's active tab javascript "window.getSelection().toString();"
        else if it is application "Microsoft Word" then
            set selectedText to text of selection
        else
            -- 尝试通用selected text属性,适配多数支持脚本的应用
            set selectedText to selected text
        end if
    end tell
on error
    -- 原生接口失败时,使用剪贴板作为备选方案
    set savedClipboard to the clipboard
    tell application "System Events" to keystroke "c" using {command down}
    delay 0.2 -- 缩短延迟,根据实际场景调整
    set selectedText to the clipboard
    set the clipboard to savedClipboard
end try

return selectedText

Swift调用代码(只需替换原脚本内容)

func readSelectedText() {
    let script = """
    set frontApp to path to frontmost application as text
    set appName to name of application frontApp

    try
        tell application appName
            if it is application "Safari" then
                set selectedText to selected text of front document
            else if it is application "Google Chrome" then
                set selectedText to execute front window's active tab javascript "window.getSelection().toString();"
            else if it is application "Microsoft Word" then
                set selectedText to text of selection
            else
                set selectedText to selected text
            end if
        end tell
    on error
        set savedClipboard to the clipboard
        tell application "System Events" to keystroke "c" using {command down}
        delay 0.2
        set selectedText to the clipboard
        set the clipboard to savedClipboard
    end try

    return selectedText
    """

    var error: NSDictionary?
    if let appleScript = NSAppleScript(source: script), let output = appleScript.executeAndReturnError(&error).stringValue {
        print("Selected text:", output)
    } else {
        print("AppleScriptError: \(String(describing: error))")
    }
}

二、使用Accessibility API(最通用方案)

macOS的辅助功能API可以直接读取UI元素的选中内容,几乎支持所有应用,无需依赖剪贴板,但需要用户授权辅助权限。

Swift实现代码

import ApplicationServices

func getSelectedTextViaAccessibility() -> String? {
    // 获取当前前台应用PID
    guard let frontAppPID = NSWorkspace.shared.frontmostApplication?.processIdentifier else {
        return nil
    }

    // 创建应用AXUIElement
    let appElement = AXUIElementCreateApplication(frontAppPID)
    
    // 获取当前聚焦的UI元素
    var focusedElement: AnyObject?
    let focusStatus = AXUIElementCopyAttributeValue(appElement, kAXFocusedUIElementAttribute as CFString, &focusedElement)
    guard focusStatus == .success, let element = focusedElement as? AXUIElement else {
        return nil
    }

    // 尝试读取聚焦元素的选中文本
    var selectedText: AnyObject?
    let textStatus = AXUIElementCopyAttributeValue(element, kAXSelectedTextAttribute as CFString, &selectedText)
    if textStatus == .success, let text = selectedText as? String {
        return text
    }

    // 聚焦元素无选中内容时,遍历窗口子元素查找选中文本(适配浏览器等场景)
    var windowElement: AnyObject?
    let windowStatus = AXUIElementCopyAttributeValue(appElement, kAXFocusedWindowAttribute as CFString, &windowElement)
    guard windowStatus == .success, let window = windowElement as? AXUIElement else {
        return nil
    }

    var windowChildren: AnyObject?
    let childrenStatus = AXUIElementCopyAttributeValue(window, kAXChildrenAttribute as CFString, &windowChildren)
    if childrenStatus == .success, let children = windowChildren as? [AXUIElement] {
        for child in children {
            var childSelectedText: AnyObject?
            let childTextStatus = AXUIElementCopyAttributeValue(child, kAXSelectedTextAttribute as CFString, &childSelectedText)
            if childTextStatus == .success, let text = childSelectedText as? String {
                return text
            }
        }
    }

    return nil
}

权限配置

  1. 在应用的Info.plist中添加NSAccessibilityUsageDescription键,填写权限申请说明(如“需要读取应用选中文本以提供快捷操作”)。
  2. 用户需在系统设置 > 隐私与安全性 > 辅助功能中,开启你的应用权限。

方案对比

  • 改进版AppleScript:无需额外权限,实现简单,但仅支持有脚本接口的应用,小众应用可能失效。
  • Accessibility API:支持所有应用,可靠性最高,但需要用户授权辅助权限,代码复杂度稍高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 17:07:50