Swift通过Accessibility API操作外部Safari触发返回上一页的方法咨询
Safari 后退功能无障碍API实现方案
核心思路是从应用根AX元素出发,逐层获取子元素,通过固定属性匹配定位后退按钮,再执行按压动作,不要硬编码UI层级避免版本兼容问题。
步骤1:获取Safari当前活动窗口
你当前拿到的是应用级AX元素,后退按钮在窗口层级下,首先从根元素的AXFocusedWindow属性取当前前台窗口:
let safariApp = AXUIElementCreateApplication(win.getSafariPid()) var focusedWindow: AnyObject? let windowResult = AXUIElementCopyAttributeValue( safariApp, kAXFocusedWindowAttribute as CFString, &focusedWindow ) // 校验返回值,成功才继续,权限不足/窗口不存在直接终止 guard windowResult == .success, let window = focusedWindow as! AXUIElement? else { return }
步骤2:递归遍历元素树定位后退按钮
不同macOS、Safari版本的UI层级不固定,写通用递归函数遍历所有子元素,通过不随系统语言变化的AXIdentifier属性匹配后退按钮,匹配规则:
- 元素角色
AXRole为AXButton - 元素标识
AXIdentifier值为BackButton(Safari全版本固定标识,不受语言设置影响)
递归查找函数实现:
func findBackButton(in element: AXUIElement) -> AXUIElement? { var children: AnyObject? // 取当前元素的子节点列表 let childResult = AXUIElementCopyAttributeValue( element, kAXChildrenAttribute as CFString, &children ) guard childResult == .success, let childList = children as? [AXUIElement] else { return nil } for child in childList { // 先检查当前节点是不是目标按钮 var role: AnyObject? var identifier: AnyObject? AXUIElementCopyAttributeValue(child, kAXRoleAttribute as CFString, &role) AXUIElementCopyAttributeValue(child, kAXIdentifierAttribute as CFString, &identifier) if let roleStr = role as? String, roleStr == kAXButtonRole as String, let idStr = identifier as? String, idStr == "BackButton" { return child } // 不是目标就递归查子节点 if let target = findBackButton(in: child) { return target } } return nil }
如果你当前使用的Safari版本匹配不到,可以在遍历的时候打印每个按钮的
AXIdentifier和AXDescription值,核对当前版本的后退按钮标识,大版本更新偶尔会调整标识字符串。
步骤3:执行按钮按压动作触发后退
拿到后退按钮元素后,直接调用AXUIElementPerformAction执行系统内置的AXPress动作即可:
guard let backButton = findBackButton(in: window) else { return } let pressResult = AXUIElementPerformAction(backButton, kAXPressAction as CFString) // pressResult为.success即代表动作触发成功
注意事项
- 调用前必须确保你的应用已在系统设置>隐私与安全性>辅助功能中获得授权,否则所有AX接口调用会返回
kAXErrorNotAuthorized错误码 - 不要硬编码UI层级(比如强制写第0个子节点的第2个子节点是工具栏),Safari小版本迭代都可能调整层级,用属性匹配的方式兼容性最好
- 如果需要判断后退按钮是否可用,可以额外查询按钮的
kAXEnabledAttribute属性,值为false时代表当前没有可回退的历史记录,按钮是置灰状态
内容的提问来源于stack exchange,提问作者Christian
相关产品推荐
相关产品推荐

