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

如何将获取Safari窗口UI元素的AppleScript代码转换为Swift代码?

解决方案

前置依赖与权限要求

  • 首先需要导入AppKit与Accessibility框架
  • 你的应用需要先获得系统辅助功能权限,才能调用AX系列接口读取其他进程的UI元素

完整实现代码

import AppKit
import Accessibility

// 获取Safari进程PID
guard let safariPID = NSWorkspace.shared.runningApplications.first(where: { $0.localizedName == "Safari" })?.processIdentifier else {
    print("未找到运行中的Safari进程")
    exit(1)
}

// 创建Safari应用的AX引用
let safariApp = AXUIElementCreateApplication(safariPID)

// 获取所有窗口
var windows: AnyObject?
let windowsStatus = AXUIElementCopyAttributeValue(safariApp, kAXWindowsAttribute as CFString, &windows)
guard windowsStatus == .success, let windowList = windows as? [AXUIElement], let firstWindow = windowList.first else {
    print("获取Safari窗口失败,错误码:\(windowsStatus.rawValue)")
    exit(1)
}

// --------------- 后续获取窗口UI元素的代码 ---------------
// 获取当前窗口的直接子UI元素(对应原AppleScript的get UI elements)
var childrenElements: AnyObject?
let childrenStatus = AXUIElementCopyAttributeValue(firstWindow, kAXChildrenAttribute as CFString, &childrenElements)
guard childrenStatus == .success, let uiElements = childrenElements as? [AXUIElement] else {
    print("获取窗口UI元素失败,错误码:\(childrenStatus.rawValue)")
    exit(1)
}

// 输出所有直接子UI元素
print("窗口第一层UI元素数量:\(uiElements.count)")
uiElements.enumerated().forEach { index, element in
    // 可选:获取元素的角色描述用于识别
    var role: AnyObject?
    AXUIElementCopyAttributeValue(element, kAXRoleDescriptionAttribute as CFString, &role)
    print("第\(index+1)个元素类型:\(role as? String ?? "未知")")
}

// 可选:递归获取窗口下所有层级的UI元素
func getAllSubElements(from element: AXUIElement) -> [AXUIElement] {
    var result = [AXUIElement]()
    var children: AnyObject?
    guard AXUIElementCopyAttributeValue(element, kAXChildrenAttribute as CFString, &children) == .success,
          let childrenList = children as? [AXUIElement] else {
        return result
    }
    result.append(contentsOf: childrenList)
    childrenList.forEach { result.append(contentsOf: getAllSubElements(from: $0)) }
    return result
}

// 调用递归方法获取所有元素
let allUIElements = getAllSubElements(from: firstWindow)
print("窗口所有层级UI元素总数量:\(allUIElements.count)")

代码说明

  • 原AppleScript中获取窗口UI元素的逻辑,对应AX框架中对窗口元素查询kAXChildrenAttribute属性的操作
  • 代码中加入了完整的错误状态判断,避免强制解包崩溃,你可以根据自己的需求调整错误处理逻辑
  • 提供了可选的递归遍历方法,可以拿到窗口下所有层级的嵌套UI元素

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 21:54:00