Search code examples
swiftmacosaccessibility

Swift MacOs - Accessibility - AxError: cannot complete


I'm trying to create a fuction, that will return selected text in any application. For that purpose I'm using Accessibiliy API, and my function looks like:

func getSelectedText() -> String? {
    // Get the currently active application
    guard let frontmostApplication = NSWorkspace.shared.frontmostApplication,
        let runningApplication = NSRunningApplication(processIdentifier: frontmostApplication.processIdentifier) else {
            return nil
    }

    // Get the AXUIElement for the application
    let applicationElement = AXUIElementCreateApplication(frontmostApplication.processIdentifier)

    var focusedElement: CFTypeRef?
    let result = AXUIElementCopyAttributeValue(
        applicationElement,
        kAXSelectedTextAttribute as CFString,
        &focusedElement
    )
    // !!! result = AxError: cannotComplete !!!
    if result != .success {
       return nil
    }

    let focusedUIElement = focusedElement as! AXUIElement

    // Get the selected text
    var selectedText: AnyObject?
    let selectedTextResult = AXUIElementCopyAttributeValue(focusedUIElement, kAXSelectedTextAttribute as CFString, &selectedText)

    if selectedTextResult == .success, let selectedText = selectedText as? String {
        return selectedText
    } else {
        // Try getting the value of the focused element instead
        var value: AnyObject?
        let valueResult = AXUIElementCopyAttributeValue(focusedUIElement, kAXValueAttribute as CFString, &value)

        if valueResult == .success, let value = value as? String {
            return value
        } else {
            return nil
        }
    }
}

However, I'm getting AxError: cannot compete on the following line:

let result = AXUIElementCopyAttributeValue(
    applicationElement,
    kAXSelectedTextAttribute as CFString,
    &focusedElement
)

App Sandbox is enabled, accessibility is also granted for this app in OS, not sure is there any other reason to fail like that?

EDIT

When I try to request permission using the following:

let prompt = kAXTrustedCheckOptionPrompt.takeUnretainedValue() as String
let options: NSDictionary = [prompt: true]
let appHasPermission = AXIsProcessTrustedWithOptions(options)

appHasPermission param is false


Solution

  • Unfortunately, Accessibility API isn't available for sandboxed apps. You should turn the sandboxing off.