Я пытаюсь получить выделенный текст, когда пользователь нажимает глобальный ярлык. Мое приложение должно читать текст, который в данный момент выбран, независимо от того, является ли текущее приложение хромом, сафари или Microsoft Word.
Я пытаюсь сделать это с помощью AppleScript, который делает это с помощью взлома буфера обмена. Однако это работает не во всех приложениях.
func readSelectedText() {
let script = """
-- Back up clipboard contents:
set savedClipboard to the clipboard
-- Copy selected text to clipboard:
tell application "System Events" to keystroke "c" using {command down}
delay 1 -- Without this, the clipboard may have stale data.
set theSelectedText to the clipboard
delay 1 -- Without this delay, may restore clipboard before pasting.
-- Restore clipboard:
set the clipboard to savedClipboard
return theSelectedText
"""
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))")
}
}
Есть ли надежный способ сделать это в любом приложении?
I'm trying to get the selected text ...
, вы можете использовать NSPasteboard.general.string(forType: .string)
, чтобы получить выделенный текст, см.: developer.apple.com/documentation/appkit/nspasteboardДанные помещаются на глобальный монтажный стол, когда приложение переходит в фоновый режим, и извлекаются из глобального монтажного стола, когда приложение становится самым передним приложением. Вы можете попробовать переключить приложение в дополнение к задержке.
Является ли любое приложение каждым приложением или конкретным приложением? Вы пытались получить текст с помощью API специальных возможностей?
Для этого вы можете использовать API специальных возможностей:
import ApplicationServices
import Cocoa
func getSelectedText() -> String? {
let systemWideElement = AXUIElementCreateSystemWide()
var selectedTextValue: AnyObject?
let errorCode = AXUIElementCopyAttributeValue(systemWideElement, kAXFocusedUIElementAttribute as CFString, &selectedTextValue)
if errorCode == .success {
let selectedTextElement = selectedTextValue as! AXUIElement
var selectedText: AnyObject?
let textErrorCode = AXUIElementCopyAttributeValue(selectedTextElement, kAXSelectedTextAttribute as CFString, &selectedText)
if textErrorCode == .success, let selectedTextString = selectedText as? String {
return selectedTextString
} else {
return nil
}
} else {
return nil
}
}
Для этого необходимо установить Privacy - AppleEvents Sending Usage Description
в Info.plist и установить com.apple.security.temporary-exception.apple-events
, чтобы иметь com.apple.systemevents
.
Вы говорите о NSServices?