ios - 使用 dataTask 的 NSURLCaching 无法在离线时使用 NSURLRequest 读取缓存
问题描述
我对 iOS 缓存系统感到非常困惑。它应该是直截了当的,但它不是(对我来说)。我正在编写一个数据库应用程序,它允许外部网络以网页的形式访问有限范围的附加参考资料。有时,用户可能需要在没有 WiFi 或 Cell 数据的现场访问外部网页。很简单,我想,在互联网可用时迭代外部页面集时使用 URLCaching。然后,使用 NSURLRequestReturnCacheDataElseLoad 的请求策略。所以,我在 AppDelegate 中创建了一个共享缓存,然后是一个单例会话:
NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
sessionConfig.URLCache = self->_myCache;
sessionConfig.requestCachePolicy = NSURLRequestReturnCacheDataElseLoad;
sessionConfig.HTTPMaximumConnectionsPerHost = 5;
session = [NSURLSession sessionWithConfiguration:sessionConfig
delegate:self
delegateQueue:nil];
然后使用 dataTask 填充缓存(因为试用 downloadTask 没有填充缓存):
NSURLSessionDataTask *myTask = [[NSURLSessionDataTask alloc] init];
do {
myTask = [self.session dataTaskWithRequest:req];
myTask.taskDescription = searchName; //Iterating several values of searchName
[myTask resume]; } while ...searchNames...
这会填充缓存,如 cache.currentDiskUsage 和 cache.currentMemoryUsage 所示。在初始提取后运行 Web 读取循环不会进一步增加缓存大小。
这是问题:在 关闭互联网的情况下运行此代码片段无法从缓存中读取
NSURL *nsurl=[NSURL URLWithString:@"https:searchName"];
NSURLRequest *nsrequest = [NSURLRequest requestWithURL:nsurl cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:60.0];
[_webView loadRequest:nsrequest];
此外,一旦缓存被填满,尝试在互联网关闭的情况下重复第一轮提取,会导致
TIC TCP Conn Failed [1:0x6000028ce580]: 1:50 Err(50)
如果填充 dataTask 并使用 NSURLRequest 从缓存中读取,HTTP 之间是否没有缓存互操作性?我究竟做错了什么?是否有不同的方法来解决我的设计目标?
解决方案
经过三天的实验,我能够创建一个包含大约 300 个网页(以及相关的嵌入图像)的缓存,并在应用程序启动时从持久内存中读回它们。访问缓存的唯一方法是使用 NSURLCache cachedResponseForRequest: 方法。使用具有适当 CachePolicy 的其他形式访问 URL 似乎不起作用。
cachedResponseForRequest: 方法似乎确实有一个不幸的副作用,因为它只将原始 html 文档传递给 wkwebview,并且没有经过验证的链接资源也在我的缓存中。
有没有人建议获得这个限制?
推荐阅读
- excel - 合并单元格,除非单元格包含某些文本
- ios - 如果 modalPresentationStyle 设置为 .custom,UIKit 将在视图控制器演示期间使用什么动画
- php - 如何为自定义帖子类型类别获取当前类别的父类别
- leaflet - React 中的 LeafletSlider
- typescript - 看不到 typescript mixins 的属性
- c++ - 在 Swift 5 中使用 Armadillo C++ 库
- cookies - 使用会话的带有 API 的 CSRF SPA
- install4j - Install4j 在启动时显示错误的语言
- javascript - Discord.js Mineflayer 不会获取 api json 并打印出来
- python - 如何将firebase android项目连接到python firebase