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

如何让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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:50:50