iOS预加载Web页面方案

可以预加载多个网址,然后在离线状态去显示那几个网址,看看是不是都完全缓存下来了。

使用方法

在需要开启预加载的地方创建

self.sCache = [STMURLCache create:^(STMURLCacheMk *mk) {

mk.whiteListsHost(whiteLists).whiteUserAgent(@"starming");

}];

这里是所有可设置项目,默认设置可以查看 model 的 get 方法

- (STMURLCacheMk *(^)(NSUInteger)) memoryCapacity; //内存容量

- (STMURLCacheMk *(^)(NSUInteger)) diskCapacity;

//本地存储容量

- (STMURLCacheMk *(^)(NSUInteger)) cacheTime;

//缓存时间

- (STMURLCacheMk *(^)(NSString *)) subDirectory;

//子目录

- (STMURLCacheMk *(^)(BOOL)) isDownloadMode;

//是否启动下载模式

- (STMURLCacheMk *(^)(NSArray *)) whiteListsHost; //域名白名单

- (STMURLCacheMk *(^)(NSString *)) whiteUserAgent; //WebView的user-agent白名单

- (STMURLCacheMk *(^)(NSString *)) addHostWhiteList;

//添加一个域名白名单

- (STMURLCacheMk *(^)(NSString *)) addRequestUrlWhiteList; //添加请求白名单

//NSURLProtocol相关设置

- (STMURLCacheMk *(^)(BOOL)) isUsingURLProtocol; //是否使用NSURLProtocol,默认使用NSURLCache

也可以随时更新这些设置项

[self.sCache update:^(STMURLCacheMk *mk) {

mk.isDownloadMode(YES);

}];

预加载名单可以按照整个 web 页面请求进行预加载

[self.sCache preLoadByWebViewWithUrls:@[@"http://www.v2ex.com",@"http://www.github.com"];

如果需要按照单个资源列表进行预加载可以使用 preLoadByRequestWithUrls 这个方法。

白名单设置

对于只希望缓存特定域名或者地址的可以通过白名单进行设置,可以在创建时进行设置或者更新时设置。

NSString *whiteListStr = @"www.starming.com||www.v2ex.com|";

NSMutableArray *whiteLists = [NSMutableArray arrayWithArray:[whiteListStr componentsSeparatedByString:@"|"]];

self.sCache = [STMURLCache create:^(STMURLCacheMk *mk) {

mk.whiteListsHost(whiteLists).whiteUserAgent(@"starming");

}];

这里的 whiteUserAgent 的设置会设置 webview 的 UserAgent,这样能够让webview以外的网络请求被过滤掉。

基本加载缓存实现原理

创建 STMURLCache 后设置 NSURLCache 的 URLCache ,在 cachedResponseForRequest 方法中获取 NSURLRequest 判断白名单,检验是否有与之对应的 Cache ,有就使用本地数据返回 NSCachedURLResponse ,没有就通过网络获取数据数据缓存。 STMURLCache 对象释放时将 NSURLCache 设置为不缓存,表示这次预加载完成不需要再缓存。当缓存空间超出设置大小会将其清空。

使用 NSURLProtocol 这种原理基本类似。

白名单实现原理

创建域名列表设置项 whiteListsHost 和 userAgent 设置项,在创建和更新时对其进行设置。在网络请求开始通过设置项进行过滤。具体实现如下

//对于域名白名单的过滤

if (self.mk.cModel.whiteListsHost.count > 0) {

id isExist = [self.mk.cModel.whiteListsHost objectForKey:[self hostFromRequest:request]];

if (!isExist) {

return nil;

}

}

//User-Agent来过滤

if (self.mk.cModel.whiteUserAgent.length > 0) {

NSString *uAgent = [request.allHTTPHeaderFields objectForKey:@"User-Agent"];

if (uAgent) {

if (![uAgent hasSuffix:self.mk.cModel.whiteUserAgent]) {

return nil;

}

}

}

具体缓存实现

缓存的实现有两种,一种是 NSURLCache 另一种是 NSURLProtocol , STMURLCache 同时支持了这两种,通过 STMURLCacheModel 里的 isUsingURLProtocol 设置项来选择使用哪个。

NSURLCache的实现

没有缓存的 request 会对其进行请求将获取数据按照hash地址存两份于本地,一份是数据,一份记录时间和类型,时间记录可以用于判断失效时间。对于判断是否有缓存可以根据请求地址对应的文件进行判断。具体实现如下:

- (NSCachedURLResponse *)localCacheResponeWithRequest:(NSURLRequest *)request {

__block NSCachedURLResponse *cachedResponse = nil;

NSString *filePath = [self filePathFromRequest:request isInfo:NO];

NSString *otherInfoPath = [self filePathFromRequest:request isInfo:YES];

NSDate *date = [NSDate date];

NSFileManager *fm = [NSFileManager defaultManager];

if ([fm fileExistsAtPath:filePath]) {

//有缓存文件的情况

BOOL expire = false;

NSDictionary *otherInfo = [NSDictionary dictionaryWithContentsOfFile:otherInfoPath];

if (self.cacheTime > 0) {

NSInteger createTime = [[otherInfo objectForKey:@"time"] integerValue];

if (createTime + self.cacheTime < [date timeIntervalSince1970]) {

expire = true;

}

}

if (expire == false) {

//从缓存里读取数据

NSData *data = [NSData dataWithContentsOfFile:filePath];

NSURLResponse *response = [[NSURLResponse alloc] initWithURL:request.URL MIMEType:[otherInfo objectForKey:@"MIMEType"] expectedContentLength:data.length textEncodingName:[otherInfo objectForKey:@"textEncodingName"]];

NSCachedURLResponse *cachedResponse = [[NSCachedURLResponse alloc] initWithResponse:response data:data];

return cachedResponse;

} else {

//cache失效了

[fm removeItemAtPath:filePath error:nil];

//清除缓存data

[fm removeItemAtPath:otherInfoPath error:nil]; //清除缓存其它信息

return nil;

}

} else {

//从网络读取

self.isSavedOnDisk = NO;

id isExist = [self.responseDic objectForKey:request.URL.absoluteString];

if (isExist == nil) {

[self.responseDic setValue:[NSNumber numberWithBool:TRUE] forKey:request.URL.absoluteString];

NSURLSession *session = [NSURLSession sharedSession];

NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {

if (error) {

cachedResponse = nil;

} else {

NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"%f",[date timeIntervalSince1970]],@"time",response.MIMEType,@"MIMEType",response.textEncodingName,@"textEncodingName", nil];

BOOL resultO = [dic writeToFile:otherInfoPath atomically:YES];

BOOL result = [data writeToFile:filePath atomically:YES];

if (resultO == NO || result == NO) {

} else {

}

cachedResponse = [[NSCachedURLResponse alloc] initWithResponse:response data:data];

}

}];

[task resume];

return cachedResponse;

}

return nil;

}

}

NSURLProtocol的实现

(责任编辑:ioter)

ios首次加载web_iOS预加载Web页面方案相关推荐

  1. javascript图片懒加载与预加载的分析

    懒加载与预加载的基本概念. 懒加载也叫延迟加载:前一篇文章有介绍:JS图片延迟加载 延迟加载图片或符合某些条件时才加载某些图片. 预加载:提前加载图片,当用户需要查看时可直接从本地缓存中渲染. 两种技 ...

  2. 基于jQuery的图片异步加载和预加载实例

    如今的网页中有很多图片,比如相册列表,那么如果一次性读取图片将会瞬间加重服务器的负担,所以我们用jQuery来实现图片的异步加载和预加载功能,这样在页面的可视范围内才会加载图片,当拖动页面至可视界面时 ...

  3. jquery 当页面图片加载之后_图片的懒加载和预加载

    一.懒加载 [1.1]什么是懒加载? 懒加载也就是延迟加载,指的是在长网页中延迟加载图像,是一种很好优化网页性能的方式.当访问一个页面的时候,先把img元素或是其他元素的背景图片路径替换成一张大小为1 ...

  4. 页面优化之懒加载与预加载

    1.前言 PC端网速较快,现在普通都是百兆宽带,那么折算一下就是10M/s的下载速度,基本上资源如果在10M以内的话加载还是比较快的. 但是移动端就不行了.移动端需要消耗巨额的流量,所以尽量减少移动端 ...

  5. css 同步加载,同步加载,异步加载,懒加载,预加载

    同步加载 默认的就是同步加载 同步加载: 同步模式又称阻塞模式,会阻止浏览器的后续处理,停止了后续的文件的解析,执行,如图像的渲染.流览器之所以会采用同步模式,是因为加载的js文件中有对dom的操作, ...

  6. img加载本地图片_图片加载技术-懒加载和预加载

    懒加载也就是延迟加载. 具体表现为: 当访问一个页面的时候,先把img元素或是其他元素的背景图片路径替换成一张占位图的路径,这样就只需请求一次,只有当图片出现在浏览器的可视区域内时,才设置图片正真的路 ...

  7. 图片的懒加载和预加载?

    一.写在前面 图片的懒加载和图片的预加载都是前端性能优化的一个方案,当然可能存在不同的应用场景,下面我们将总结一下这两个方案. 二.图片懒加载 图片的懒加载是什么? 图片的懒加载指的是在长网页中延迟加 ...

  8. Jquery图片懒加载和预加载

    Jquery图片懒加载和预加载 懒加载 1.什么是懒加载 Lazy Load也叫懒加载,延迟加载,顾名思义,就是在图片未到达可视区域时,不加载图片,我们常常在很多的优秀网站上看到类似的例子,例如迅雷. ...

  9. 懒加载和预加载的区别

    概念: 懒加载:懒加载也叫延迟加载,JS图片延迟加载,延迟加载图片或符合某些条件时才加载某些图片. 预加载:提前加载图片,当用户需要查看时可直接从本地缓存中渲染. 区别: 两者的行为是相反的,预加载是 ...

  10. iOS 实现简单的列表预加载

    在大部分 App 中,在有 feeds 流之类列表的地方,由于后端数据一般采用分页加载,为了用户体验需要做预加载.最简单的加载方式,就是当列表显示的内容达到一定的数量时候,自动请求下一个分页. 加载策 ...

最新文章

  1. 阿里云智能 AIoT 首席科学家丁险峰:阿里全面进军IoT这一年 | 问底中国IT技术演进...
  2. 杨老师课堂之JavaScript定时器限时抢购秒杀商品案例
  3. JDK源码分析——Java的SPI机制分析与实战
  4. java框架_2020年Java框架排行榜,谁居榜首?
  5. redis在windows10上跑起来
  6. 【ubuntu】ubuntu如何改变系统用户名
  7. 将java项目做成app_将鸿蒙做成和EMUI一致,又兼容安卓APP,华为已立于不败之地...
  8. Linux学习笔记-消息队列的打开、创建、控制
  9. js java webservice_js调用webservice中的方法实现思路及代码
  10. 视频教程-企业级多语言舆情爬虫系统-Go语言
  11. kubeedge v1.1.0部署指南
  12. 语法长难句-----名词和名词性从句
  13. python使用selenium爬取dell官网驱动(一):获取遍历各驱动的下载网址
  14. 如何下载网页上的图片
  15. 初学者如何学好编程?
  16. jQuery选择器之类选择器
  17. JAVA面向对象学习心得
  18. 在线博客系统——获取用户信息,退出登录
  19. MPLS基础概述MP-BGP实验(华为 DataCome)
  20. MyEclipse下载地址

热门文章

  1. 绑定touch事件后click无效,vue项目解决棒法
  2. Maven具体解释之------maven版本号管理
  3. SpringData ES中一些底层原理的分析
  4. Java千百问_06数据结构(003)_什么是基本类型包装器
  5. 8-06. 畅通project之局部最小花费问题(35)(最小生成树_Prim)(ZJU_PAT)
  6. typedef NS_ENUM 等枚举介绍
  7. Python中执行系统命令常见的几种方法
  8. ios开发中如何隐藏各种bar
  9. 嵌入式Linux进程信息及内存布局
  10. linux下用户态程序coredump生成方法