如何让UITests-Runner获取隐私敏感数据权限(相册场景)
解决UITests-Runner无法获取相册权限保存截图的问题
我完全懂你的痛点——真机测试时想直接把UITest截图存到相册,不用每次折腾下载App容器,但直接在UITest里调用UIImageWriteToSavedPhotosAlbum()总是崩溃,配置了权限描述也没用,连授权弹窗都看不到。这其实是UITest Runner的特殊运行机制导致的,咱们一步步解决:
为什么你的方法行不通?
UITests-Runner是个后台辅助进程,它没有自己的交互UI界面。iOS系统只会给有可视化界面的App弹出隐私权限请求框,所以哪怕你在UITest Target和主App的Info.plist里都加了NSPhotoLibraryAddUsageDescription,Runner进程也没法触发授权流程,自然会因为权限不足崩溃。
可行的解决方案:让主App帮你保存截图
既然Runner没法处理权限,那就把保存操作交给有UI的主App来做,具体分三步:
1. 给主App配置正确的权限描述
确保主App的Info.plist里已经添加:
NSPhotoLibraryAddUsageDescription:填写清晰的权限说明,比如“保存UITest截图到相册,方便快速查看测试结果”- (如果后续需要读取相册可补充
NSPhotoLibraryUsageDescription,当前场景仅需添加权限,前者足够)
2. 给主App和UITest配置App Group共享目录
UITest进程和主App是相互独立的,需要通过共享目录传递截图数据:
- 在开发者后台创建一个App Group(比如
group.com.yourcompany.yourapp.test) - 在Xcode中,分别给主App Target和UITest Target开启App Groups功能,添加刚才创建的Group ID
3. 编写代码实现跨进程截图传递与保存
在UITest里:生成截图并保存到共享目录
- (void)testExample { // 生成测试截图 XCUIScreenshot *screenshot = [_app screenshot]; NSData *imageData = UIImagePNGRepresentation(screenshot.image); // 获取共享目录路径 NSURL *groupContainerURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.com.yourcompany.yourapp.test"]; NSURL *screenshotFileURL = [groupContainerURL URLByAppendingPathComponent:@"uitest_screenshot.png"]; // 把截图写入共享目录 [imageData writeToURL:screenshotFileURL atomically:YES]; // 触发主App检查共享目录(这里用简单的屏幕点击示例,也可以用通知、定时器等方式) [_app tap]; }
在主App里:监听并处理共享目录的截图
在主App的主ViewController里添加以下代码,用来检查共享目录并保存截图:
- (void)viewDidLoad { [super viewDidLoad]; // 添加屏幕点击手势,触发截图检查逻辑 UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(checkForSharedScreenshot)]; [self.view addGestureRecognizer:tap]; } - (void)checkForSharedScreenshot { NSURL *groupContainerURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.com.yourcompany.yourapp.test"]; NSURL *screenshotFileURL = [groupContainerURL URLByAppendingPathComponent:@"uitest_screenshot.png"]; // 如果共享目录里存在截图文件 if ([[NSFileManager defaultManager] fileExistsAtPath:screenshotFileURL.path]) { NSData *imageData = [NSData dataWithContentsOfURL:screenshotFileURL]; UIImage *screenshotImage = [UIImage imageWithData:imageData]; // 保存到相册 UIImageWriteToSavedPhotosAlbum(screenshotImage, self, @selector(imageSavedCallback:didFinishSavingWithError:contextInfo:), NULL); // 删除临时文件,避免重复处理 [[NSFileManager defaultManager] removeItemAtURL:screenshotFileURL error:nil]; } } // 保存结果回调 - (void)imageSavedCallback:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo { if (error) { NSLog(@"截图保存失败:%@", error.localizedDescription); } else { NSLog(@"截图已成功保存到相册!"); } }
额外提示
第一次运行主App时,系统会弹出相册权限请求框,点击“允许”后,后续的保存操作就会自动完成,不用再重复授权。这样你在UITest运行后,主App就会自动把截图存到相册里,真机上直接就能查看,完全符合你想要的便捷性需求。
内容的提问来源于stack exchange,提问作者Kjuly
相关产品推荐
相关产品推荐

