Xcode 15中PINRemoteImage未调用canInitWithRequest致Stub失效求助
Xcode 15下PINRemoteImage结合OHHTTPStubs的Mock功能失效问题排查与解决思路
问题背景
- 项目使用
PINRemoteImage作为图片加载框架,搭配OHHTTPStubs做网络请求Mock测试,在Xcode 14中运行完全正常 - 升级到Xcode 15后,图片请求的Stub功能彻底失效,但其他接口的Mock仍正常工作,直接用
NSURLSession发起的标准请求也能被正常Stub - 深入调试发现:Xcode 15环境下,
PINRemoteImage加载图片时,NSURLProtocol的+ (BOOL)canInitWithRequest:(NSURLRequest *)request方法不再被调用——这是OHHTTPStubs实现请求拦截的核心入口,Xcode 14中该方法会被正常触发
可能的底层变更原因
Xcode 15对应的iOS 17 SDK中,NSURLSession的请求处理逻辑存在隐性调整:
- 针对图片这类特定资源的加载,系统可能启用了新的优化路径,绕过了
NSURLProtocol的拦截机制 PINRemoteImage内部默认的NSURLSessionConfiguration可能在新SDK下被自动启用了某些私有配置,导致请求不经过NSURLProtocol的校验流程
可行的解决思路
1. 手动为PINRemoteImage的Session配置添加Protocol
找到项目中初始化PINRemoteImageManager的代码,手动将OHHTTPStubsProtocol注入到Session的配置中,强制让请求走Protocol拦截:
// 自定义Session配置,添加OHHTTPStubsProtocol NSURLSessionConfiguration *stubConfig = [NSURLSessionConfiguration defaultSessionConfiguration]; stubConfig.protocolClasses = @[[OHHTTPStubsProtocol class]]; // 用自定义配置初始化PINRemoteImageManager,并设置为全局共享实例 PINRemoteImageManager *stubEnabledManager = [[PINRemoteImageManager alloc] initWithSessionConfiguration:stubConfig]; [PINRemoteImageManager setSharedManager:stubEnabledManager];
2. 调整PINRemoteImage的请求逻辑
如果上述方法无效,可以尝试修改PINRemoteImage的内部实现,确保它使用标准的NSURLSessionDataTask发起请求,避免触发系统的私有优化路径。比如检查框架内部是否有针对图片加载的特殊Session配置,将其改为标准配置。
3. 绕过网络层的Mock方案
临时绕过网络拦截,直接MockPINRemoteImage的图片加载接口:
- 通过给
PINRemoteImageView添加分类,重写图片加载方法,直接返回测试用的本地图片 - 或者使用OC的Runtime特性,替换
PINRemoteImageManager的加载方法,在测试环境下直接返回Mock结果
补充说明
已在PINRemoteImage和OHHTTPStubs的官方仓库提交Issue,但暂未收到回复。以上思路是基于Xcode 15 SDK的底层变更推测出的可行方案,欢迎各位开发者补充其他有效的解决方法。
内容的提问来源于stack exchange,提问作者Mr.P
相关产品推荐
相关产品推荐

