XCTest中关闭Touch ID警报代码在iOS15.6突然失效求助
解决iOS 15.6中Touch ID警报关闭代码的崩溃问题
问题背景
此前运行正常的Touch ID警报关闭代码,在iOS 15.6环境下调用tap()时触发[__NSArrayM insertObject:atIndex:]: object cannot be nil (NSInvalidArgumentException)异常,这是XCTest框架在该系统版本中操作Springboard元素的已知问题。
解决方案
方案1:使用坐标点击绕过元素tap()的内部bug
直接通过元素坐标执行点击操作,避开框架内部的数组操作异常:
let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard") let allowBtn = springboard.buttons["Cancel"] if allowBtn.waitForExistence(timeout: 2) { // 获取按钮中心坐标执行点击 let centerCoordinate = allowBtn.coordinate(withNormalizedOffset: CGVector(dx: 0.5, dy: 0.5)) centerCoordinate.tap() }
方案2:使用更精确的元素匹配方式
通过firstMatch获取匹配到的第一个有效元素,避免模糊查询导致的元素实例异常:
let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard") let allowBtn = springboard.buttons.matching(identifier: "Cancel").firstMatch if allowBtn.waitForExistence(timeout: 2) { allowBtn.tap() }
如果identifier匹配失效,也可以尝试通过label属性查询:
let allowBtn = springboard.buttons.matching(label: "Cancel").firstMatch
方案3:先定位弹窗再获取按钮
直接定位Springboard中的警报弹窗,再从中获取目标按钮,减少全局元素查询的不确定性:
let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard") let alert = springboard.alerts.firstMatch if alert.waitForExistence(timeout: 2) { let cancelBtn = alert.buttons["Cancel"] if cancelBtn.exists { let centerCoordinate = cancelBtn.coordinate(withNormalizedOffset: CGVector(dx: 0.5, dy: 0.5)) centerCoordinate.tap() } }
原理说明
iOS 15.6中XCTest对Springboard元素的tap()方法内部实现存在bug,导致直接调用时触发数组插入nil的异常。上述方案通过坐标点击绕过bug、精确元素匹配确保实例有效性、缩小查询范围减少歧义三种方式,解决了该崩溃问题。
内容的提问来源于stack exchange,提问作者Eugene Gordin
相关产品推荐
相关产品推荐

