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

升级iOS15/Xcode13后addUIInterruptionMonitor无法关闭弹窗如何解决

问题原因

iOS 15 + Xcode 13 对UI测试的弹窗拦截逻辑做了3个核心变更,是原有代码失效的根因:

  • addUIInterruptionMonitor的回调触发优先级降低,系统弹窗出现后会优先走XCTest内置处理逻辑,自定义拦截器不会第一时间被调用
  • 弹窗按钮索引规则调整,原有靠element(boundBy: 0)取按钮的逻辑不再适配,部分权限弹窗的按钮顺序被系统修改,甚至部分场景下拦截器拿到的alert元素本身为空
  • 原有配套的app.tap()唤醒拦截器的逻辑失效,iOS15下该空点击大概率不会触发拦截器执行
修复方案

1. 调整拦截器实现,用按钮文字匹配替代索引定位

硬编码索引的稳定性极低,替换为按钮文字匹配的方式,同时先校验alert元素有效性:

addUIInterruptionMonitor(withDescription: "System Dialog") { alert -> Bool in
    guard alert.exists else {
        return false
    }
    // 可根据业务需要补充需要匹配的按钮文字
    let targetButtonTitles = ["不允许", "Don't Allow", "确定", "OK", "取消", "Cancel"]
    for title in targetButtonTitles {
        let targetBtn = alert.buttons[title]
        if targetBtn.exists && targetBtn.isHittable {
            targetBtn.tap()
            return true
        }
    }
    // 未匹配到目标按钮返回false,交给后续拦截器处理
    return false
}

2. 替换空点击触发逻辑,增加等待+多次尝试

iOS15下单次空点击触发拦截的概率很低,调整为等待弹窗加载完成后多次触发:

// 等待2秒确保弹窗完全弹出
Thread.sleep(forTimeInterval: 2)
// 多次尝试触发拦截器
for _ in 0..<2 {
    app.tap()
    Thread.sleep(forTimeInterval: 0.5)
}

3. 极端场景降级方案:直接访问SpringBoard系统进程处理弹窗

如果自定义拦截器完全无法触发,可以直接获取系统进程的弹窗元素,优先级高于XCTest内置拦截逻辑:

let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard")
let systemAlert = springboard.alerts.firstMatch
if systemAlert.exists {
    let targetBtn = systemAlert.buttons["不允许"]
    if targetBtn.exists {
        targetBtn.tap()
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 13:24:03