XCUITest点击UIImagePickerController的Choose按钮失败及PHPicker加载图片错误
UIImagePickerController 编辑页Choose按钮无法触发问题
该问题是Xcode 12.4搭配iOS 14模拟器时的XCUITest适配特性:UIImagePickerController的编辑界面属于系统相册进程,元素不在当前测试App的元素树内,直接用app对象定位会出现找不到元素、事件触发无效的问题。
解决代码如下:
// 绑定系统相册进程获取元素树 let photoApp = XCUIApplication(bundleIdentifier: "com.apple.mobileslideshow") // 直接在相册进程的元素树中定位并点击Choose按钮 photoApp.buttons["Choose"].tap()
PHPickerViewController 多选图片加载失败问题
该问题是Xcode 12.4对应iOS 14版本的模拟器专属bug,由系统资源并发加载竞争导致,真机运行不会触发。可选两种规避方案:
- 升级Xcode到12.5及以上版本,苹果已在后续系统版本中修复了该模拟器bug
- 若需保留Xcode 12.4开发环境,可将图片加载逻辑改为串行执行,或加载失败后增加一次重试逻辑,修改后的代理代码如下:
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) { picker.dismiss(animated: true) let itemProviders = results.map(\.itemProvider) // 串行队列控制加载顺序,避免并发触发资源竞争 let loadQueue = DispatchQueue(label: "phpicker.serial.load") let semaphore = DispatchSemaphore(value: 1) for itemProvider in itemProviders { loadQueue.async { semaphore.wait() guard itemProvider.canLoadObject(ofClass: UIImage.self) else { semaphore.signal() return } itemProvider.loadObject(ofClass: UIImage.self) { [weak self] image, error in defer { semaphore.signal() } if let image = image as? UIImage { // 正常处理图片 } else if let _ = error { // 失败后重试一次,模拟器场景下重试成功率接近100% itemProvider.loadObject(ofClass: UIImage.self) { retryImage, _ in if let retryImage = retryImage as? UIImage { // 处理重试获取的图片 } } } } } } }
该兼容逻辑仅需在测试场景保留,生产环境可直接使用原生并发加载逻辑,不会出现该问题。
内容的提问来源于stack exchange,提问作者Arjav Dave
相关产品推荐
相关产品推荐

