至于AFNetworking的缓存机制,UIWebView学习笔记

by admin on 2019年9月12日

UIWebView学习笔记

今日有相恋的人问到关于AFNetworking的缓存战略,当时想了想,自个儿有一点点的了解,可是不通晓该怎么应对,毕竟平平日听到的应有都是有关SDWebImage的局地办事规律,对于AFNetworking的钻研不深,后来再网络搜了瞬间,关于其缓存的国策介绍的小说也相当少,后来在墙外搜了有的材质,在此整治如下,供大家参照他事他说加以考察:

1. iOS 禁止使用webView加载网页的长按出现’拷贝’事件

- (void)webViewDidFinishLoad:(UIWebView *)webView {
    [self.webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitUserSelect='none';"];
    [self.webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitTouchCallout='none';"];
}

How Does Caching Work in AFNetworking? : AFImageCache & NSUrlCache
Explained

2. iOS webView长按图片,不出现’拷贝’(iOS9暗中同意就是这种效果)

AFNetworking实际上选拔了五个单身的缓存机制:AFImagecache和NSU中华VLCache.

2.1 准备好JS文件

// js文件,如:acepack_details.js
function setImageClickFunction(){
    var imgs = document.getElementsByTagName("img");
    for (var i=0;i<imgs.length;i++){
        imgs[i].style.webkitUserSelect='none';
    }
}

AFImagecache:二个提供图片内部存款和储蓄器缓存的类,承继自NSCache。

2.2 注入JS

[self.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"acepack_details" withExtension:@"js"] encoding:NSUTF8StringEncoding error:nil]];

NSURLCache:NSUEvoqueLConnection’s私下认可的UPRADOL缓存机制,用于存储NSUCR-VLResponse对象:贰个暗中同意缓存在内部存储器,通过配备能够缓存到磁盘的类。

3. webView作为tableView的tableHeaderView

  • 在webView的回调方法里,必须求再一次安装tableView的tableHeaderView,不然会油但是生意外的主题材料。

-(void)webViewDidFinishLoad:(UIWebView *)webView {
    // 获取到webview的高度
    CGFloat height = [[self.webView stringByEvaluatingJavaScriptFromString:@"document.body.scrollHeight"] floatValue];
    self.webView.frame = CGRectMake(self.webView.frame.origin.x, self.webView.frame.origin.y, ScreenWidth, height);
    // 一定要重新设置tableView的tableHeaderView,否则会出现意想不到的问题。
    [self tableView].tableHeaderView = self.webView;
}

1.AFImagecache

4. 轮换webView中的img标签的图形

  • 动用场景
    • 获取页面中具有图片,图片浏览器
    • 非WIFI景况下,加载本地图片

- (NSString *)replaceImageUrl:(NSString *) content {
    // 匹配<img>标签
    NSString *urlPattern = @"<img[^>]+?src=[\"']?([^>'\"]+)[\"']?";
    NSError *error = [NSError new];
    NSString *tmp = content;
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:urlPattern options:NSRegularExpressionCaseInsensitive error:&error ];
    // match 这块内容非常强大
    NSUInteger count =[regex numberOfMatchesInString:content options:NSRegularExpressionCaseInsensitive range:NSMakeRange(0, [content length])];// 匹配到的次数
    UIImage *img = [UIImage imageNamed:@"icon_app"];
    // 用网络图片替换webView上显示的图片
    NSString *tmpStr = @"https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/logo_white_fe6da1ec.png";
    // 用本地图片替换webView上显示的图片
    tmpStr = [self htmlForJPGImage:img];
    if(count > 0) {
        NSArray* matches = [regex matchesInString:content options:NSMatchingReportCompletion range:NSMakeRange(0, [content length])];
        for (NSTextCheckingResult *match in matches) {
            NSInteger count = [match numberOfRanges]; // 匹配项
            for(NSInteger index = 0;index < count;index++){
                NSRange halfRange = [match rangeAtIndex:index];
                if (index == 1) {
                    // 图片的src属性值
                    NSString *urlStr = [content substringWithRange:halfRange];
                    NSLog(@"=%@=",urlStr);
                    // 保存图片URL
                    [self.imgSrcArrayM addObject:[content substringWithRange:halfRange]];
                    // 替换src属性值
                    tmp = [tmp stringByReplacingOccurrencesOfString:urlStr withString: tmpStr];
                }
            }
        }
    }
    return tmp;
}

// 编码图片
- (NSString *)htmlForJPGImage:(UIImage *)image {
    NSData *imageData = UIImageJPEGRepresentation(image,1.0);
    NSString *imageSource = [NSString stringWithFormat:@"data:image/jpg;base64,%@",[imageData base64Encoding]];
    return imageSource;
}

AFImageCache是UIImageView+AFNetworking分类的一有个别。它继续自NSCache,通过叁个ULacrosseL字符串作为它的key(从NSU途达LRequest中拿走)来存款和储蓄UIImage对象。

5. webView注入JS代码

[self.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"acepack_details" withExtension:@"js"] encoding:NSUTF8StringEncoding error:nil]];

AFImagecache定义:

6. webView执行JS代码

// 调用JS里的setImageClickFunction()函数
[self.webView stringByEvaluatingJavaScriptFromString:@"setImageClickFunction()"];

亚洲必赢手机入口 1

7. webView中的图片点击事件

AFImageCache 从 AFNetworking
2.1初阶能够举办安顿了。有二个集体艺术setSharedImageCache。详细文书档案能够看这里
。它把富有可访谈的UIImage对象存到了NSCache。当UIImage对象释放之后NSCache会举行管理。假诺你想观看images什么日期释放,能够兑现NSCacheDelegate的cache:willEvictObject方法

7.1 准备好JS文件

// js文件,如:acepack_details.js
function setImageClickFunction(){
    // 取出所有的img标签
    var imgs = document.getElementsByTagName("img");
    for (var i=0;i<imgs.length;i++){
        var src = imgs[i].src;
        // 绑定事件
        imgs[i].setAttribute("onClick","clickme(src)");
    }
}

function clickme(imagesrc){
    var url="ClickImage:"+imagesrc;
    document.location = url;
}

2.NSURLCache

7.2 注入JS

[self.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"acepack_details" withExtension:@"js"] encoding:NSUTF8StringEncoding error:nil]];

既然AFNetworking使用NSURAV4LConnection,它使用了原生的缓存机制NSUEnclaveLCache。NSU兰德哈弗LCache缓存了从服务器重返的NSU奥迪Q5LResponse对象。

7.3 webView央求回调里,施行JS

// 调用JS里的setImageClickFunction()函数
[self.webView stringByEvaluatingJavaScriptFromString:@"setImageClickFunction()"];

NSUWranglerLCache的shareCache方法默许是足以利用的,缓存获取的从头到尾的经过。不幸的是,它的默许配置只是缓存在内部存款和储蓄器并未写到硬盘。为了消除那些标题,你能够证明一(Aptamil)(Dumex)个
sharedCache,像这么:

7.4 拦截要求,处理图片的单击事件

-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)_request navigationType:(UIWebViewNavigationType)navigationType {
    NSString *requestString = [[_request URL] absoluteString];
    NSString *prefix = @"clickimage:";
    if ([requestString hasPrefix:prefix]) {
        DDLogVerbose(@"%@", requestString);
        NSUInteger index = 0;
        NSRange range = [requestString rangeOfString:prefix];
        if (range.location != NSNotFound) {
            NSString *tmpSrc = [requestString substringFromIndex:(range.location + range.length)];
            index = [self.imgSrcArrayM indexOfObject:tmpSrc];
        }
        // 显示图片浏览器
        [self networkImageShow:index];
    }
    return YES;
}

亚洲必赢手机入口 2

8. 长按webView上的图纸,保存

如此,大家证明了一个2M内部存款和储蓄器,100M磁盘空间的NSUCR-VLCache。

8.1 注入JS

static NSString* const kTouchJavaScriptString=
@"document.ontouchstart=function(event){\
x=event.targetTouches[0].clientX;\
y=event.targetTouches[0].clientY;\
document.location=\"myweb:touch:start:\"+x+\":\"+y;};\
document.ontouchmove=function(event){\
x=event.targetTouches[0].clientX;\
y=event.targetTouches[0].clientY;\
document.location=\"myweb:touch:move:\"+x+\":\"+y;};\
document.ontouchcancel=function(event){\
document.location=\"myweb:touch:cancel\";};\
document.ontouchend=function(event){\
document.location=\"myweb:touch:end\";};";
[self.webView stringByEvaluatingJavaScriptFromString:kTouchJavaScriptString];

对NSU路虎极光LRequest对象设置缓存战略

8.2 管理点击UIWebView上边的图形

#pragma mark - 处理点击UIWebView上面的图片
- (BOOL)handleWebViewClickImageWithUrl:(NSString *)url{
    NSString *requestString = url;
    NSArray *components = [requestString componentsSeparatedByString:@":"];
    if ([components count] > 1 && [(NSString *)[components objectAtIndex:0]
                                   isEqualToString:@"myweb"]) {
        if([(NSString *)[components objectAtIndex:1] isEqualToString:@"touch"]) {
            //NSLog(@"you are touching!");
            //NSTimeInterval delaytime = Delaytime;
            if ([(NSString *)[components objectAtIndex:2] isEqualToString:@"start"]) {
                /*
                 @需延时判断是否响应页面内的js...
                 */
                _gesState = GESTURE_STATE_START;
                NSLog(@"touch start!");
                float ptX = [[components objectAtIndex:3]floatValue];
                float ptY = [[components objectAtIndex:4]floatValue];
                NSLog(@"touch point (%f, %f)", ptX, ptY);
                NSString *js = [NSString stringWithFormat:@"document.elementFromPoint(%f, %f).tagName", ptX, ptY];
                NSString *tagName = [self.webView stringByEvaluatingJavaScriptFromString:js];
                _imgURL = nil;
                if ([tagName isEqualToString:@"IMG"]) {
                    _imgURL = [NSString stringWithFormat:@"document.elementFromPoint(%f, %f).src", ptX, ptY];
                }
                if (_imgURL) {
                    _timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(handleLongTouch) userInfo:nil repeats:NO];
                }
            }
            else if ([(NSString *)[components objectAtIndex:2] isEqualToString:@"move"])
            {
                //**如果touch动作是滑动,则取消hanleLongTouch动作**//
                _gesState = GESTURE_STATE_MOVE;
                NSLog(@"you are move");
            }
            else if ([(NSString *)[components objectAtIndex:2]isEqualToString:@"end"]) {
                [_timer invalidate];
                _timer = nil;
                _gesState = GESTURE_STATE_END;
                NSLog(@"touch end");
            }
        }
        return NO;
    }
    return YES;
}
// 处理长按事件
- (void)handleLongTouch {
    NSLog(@"%@", _imgURL);
    if (_imgURL && _gesState == GESTURE_STATE_START) {
        UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:@"取消" destructiveButtonTitle:nil otherButtonTitles:@"保存图片", nil];
        sheet.cancelButtonIndex = sheet.numberOfButtons - 1;
        [sheet showInView:[UIApplication sharedApplication].keyWindow];
    }
}
// 弹出对话框
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
    if (actionSheet.numberOfButtons - 1 == buttonIndex) return;
    NSString *title = [actionSheet buttonTitleAtIndex:buttonIndex];
    if ([title isEqualToString:@"保存图片"]) {
        if (_imgURL) {
            NSLog(@"imgurl = %@", _imgURL);
        }
        NSString *urlToSave = [self.webView stringByEvaluatingJavaScriptFromString:_imgURL];
        NSLog(@"image url=%@", urlToSave);
        NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlToSave]];
        UIImage *image = [UIImage imageWithData:data];
        UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
    }
}
// 回调
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {
    if (error) {
        NSLog(@"Error");
    } else {
        NSLog(@"OK");
    }
}

NSU酷威LCache对各样NSURubiconLRequest对象都会遵守缓存计策(NSU陆风X8LRequestCachePolicy)。战术定义如下:

9. webView缓存

亚洲必赢手机入口,NSUTiggoLRequestUseProtocolCachePolicy:内定定义在协商落实里的缓存逻辑被用来UTiguanL央求。那是U本田UR-VL哀告的暗许计策

9.1 缓存的意思

  1. webView一般是加载UI相比复杂亮丽、可变、iOS原生控件不便于落成的分界面,所以网页的因素一般都很复杂,对处于GP宝马X3S意况下的客户来说,流量是个大标题,所以须求缓存!
  2. 当客商处于断网状态下时,为了避免顾客步向空白页面,应该把上次已经加载过的页面显示给顾客!
  3. webView的诉求一般都以GET,POST央求一般是发多量数据给服务器管理(变动性相当大),因而一般只对GET央浼举办缓存,而不对POST央浼实行缓存。

NSUCRUISERLRequestReloadIgnoringLocalCacheData:忽略本地缓存,从源加载

9.2 为何可以举办缓存?

  • NSUCRUISERLCache在各样UIWebView的的NSU福睿斯LRequest须求中都会被调用。
  • iOS 5此前:只协助内部存款和储蓄器缓存;从iOS 5初叶:同有时间帮助内部存款和储蓄器缓存和硬盘缓存。

NSU卡宴LRequestReloadIgnoringLocalAndRemoteCacheData:忽略本地&服务器缓存,从源加载

9.3 怎么实现缓存?

  • iOS设备上NSU奥迪Q5LCache暗中认可只可以实行内部存款和储蓄器缓存。能够经过子类化NSU奥迪Q7LCache来完结自定义的本子进而达成在DISK上缓存内容。
  • 亟待重写cachedResponseForRequest,这么些会在呼吁发送前会被调用,从中我们能够判断是还是不是针对此NSULX570LRequest再次回到本地数据。
  • 借使地方未有缓存就调用上面那条语句:return [super cachedResponseForRequest:request];

NSULX570LRequestReturnCacheDataElseLoad:先从缓存加载,若无缓存,从源加载

9.4 NSUPRADOLCache常用艺术

  1. 大局缓存对象

NSURLCache *cache = [NSURLCache sharedURLCache]; 
  1. 设置内部存储器缓存的最大体积(字节为单位,默认为512KB)

-(void)setMemoryCapacity:(NSUInteger)memoryCapacity;
  1. 安装硬盘缓存的最大体积(字节为单位,默以为10M)

-(void)setDiskCapacity:(NSUInteger)diskCapacity;
  1. 赢得有些伏乞的缓存

-(NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request; ```
5. 清除某个请求的缓存
``` objc
-(void)removeCachedResponseForRequest:(NSURLRequest *)request;
  1. 扫除全体的缓存

-(void)removeAllCachedResponses;

NSUKugaLRequestReturnCacheDataDontLoad离线方式,加载缓存数据(无论是或不是过期),不从源加载

9.5 设置NSU普拉多LRequest缓存计策

  • NSUEnclaveLRequestUseProtocolCachePolicy // 暗中认可的缓存计谋(取决于情商)
  • NSUKoleosLRequestReloadIgnoringLocalCacheData // 忽略缓存,重新诉求
  • NSURLRequestReloadIgnoringLocalAndRemoteCacheData // 未实现
  • NSU库罗德LRequestReloadIgnoringCacheData =
    NSUXC90LRequestReloadIgnoringLocalCacheData // 忽略缓存,重新乞请
  • NSU库罗德LRequestReturnCacheDataElseLoad //
    有缓存就用缓存,未有缓存就重新央求
  • NSU福睿斯LRequestReturnCacheDataDontLoad //
    有缓存就用缓存,未有缓存就不发必要,当做央求出错管理(用于离线格局)
  • NSURLRequestReloadRevalidatingCacheData // 未实现

NSU哈弗LRequestReloadRevalidatingCacheData存在的缓存数据先承认有效性,无效的话从源加载

3.关于互连网中的数据缓存

一、关于同一个UOdysseyL的频仍伸手

有的时候,对同贰个U安德拉L央浼多次,重临的多寡可能都以一律的,比方服务器上的某张图片,无论下载多少次,重返的数量都以一致的。

亚洲必赢手机入口 3

上边包车型客车动静会导致以下难题

(1)顾客流量的荒芜

(2)程序响应速度相当不够快

缓慢解决地点的主题材料,一般思索对数码举行缓存。

二、缓存

为了增加度序的响应速度,能够思考选取缓存(内部存款和储蓄器缓存\硬盘缓存)

亚洲必赢手机入口 4

先是次呼吁数据时,内部存款和储蓄器缓存中向来不数量,硬盘缓存中绝非多少。

缓存数据的进度

亚洲必赢手机入口 5

当服务器重临数据时,要求做以下步骤

(1)使用服务器的数据(比方分析、展现)

(2)将服务器的数码缓存到硬盘(沙盒)

那时候缓存的景观是:内存缓存中有数据,硬盘缓存中有数量。

再也恳请数据分为二种情况:

(1)假设程序并从未被关闭,一向在运维

那正是说此时内部存款和储蓄器缓存中有数量,硬盘缓存中有多少。假若那时候再一次恳请数据,直接选取内部存款和储蓄器缓存中的数据就可以

(2)假使程序重新启航

那么此时内部存款和储蓄器缓存已经销声匿迹,没有数量,硬盘缓存依然存在,还会有多少。假诺此时重新呼吁数据,须要读取内部存款和储蓄器中缓存的多寡。

升迁:从硬盘缓存中读取数据后,内部存款和储蓄器缓存中又有数量了

三、缓存的兑现

1.说明:

由于GET央浼一般用来查询数据,POST央浼一般是发多量数据给服务器管理(变动性相当的大)

因此一般只对GET供给进行缓存,而不对POST央浼进行缓存

在iOS中,能够使用NSU福睿斯LCache类缓存数据

iOS 5在此以前:只支持内部存款和储蓄器缓存。从iOS 5开头:同有的时候间援助内部存款和储蓄器缓存和硬盘缓存

2.NSURLCache

iOS中得缓存本领运用了NSUEscortLCache类。

缓存原理:叁个NSU奥迪Q5LRequest对应七个NSCachedU帕JeroLResponse

缓存技能:把缓存的数量都保留到数据库中。

3.NSU奥迪Q3LCache的大面积用法

(1)得到全局缓存对象(没要求手动成立)NSUENVISIONLCache *cache = [NSURLCache
sharedURLCache];

(2)设置内部存款和储蓄器缓存的最大容积(字节为单位,默以为512KB)-
(void)setMemoryCapacity:(NSUInteger)memoryCapacity;

(3)设置硬盘缓存的最大体量(字节为单位,默以为10M)-
(void)setDiskCapacity:(NSUInteger)diskCapacity;

(4)硬盘缓存的任务:沙盒/Library/Caches

(5)取得有个别央浼的缓存- (NSCachedU宝马X5LResponse
*)cachedResponseForRequest:(NSURLRequest *)request;

(6)清除某些央求的缓存-
(void)removeCachedResponseForRequest:(NSUCR-VLRequest *)request;

(7)清除全体的缓存- (void)removeAllCachedResponses;

4.缓存GET请求

要想对有个别GET诉求实行数据缓存,极度轻易

NSMutableURLRequest *request = [NSMutableURLRequest
requestWithURL:url];

// 设置缓存计谋

request.cachePolicy = NSURLRequestReturnCacheDataElseLoad;

假定设置了缓存战术,系统会活动利用NSUTiggoLCache进行多少缓存

5.iOS对NSU牧马人LRequest提供了7种缓存战术:(实际上能用的只有4种)

NSUSportageLRequestUseProtocolCachePolicy // 暗中同意的缓存战术(取决于情商)

NSUSportageLRequestReloadIgnoringLocalCacheData // 忽略缓存,重新央求

NSURLRequestReloadIgnoringLocalAndRemoteCacheData // 未实现

NSUPRADOLRequestReloadIgnoringCacheData =
NSUEscortLRequestReloadIgnoringLocalCacheData // 忽略缓存,重新央求

NSULANDLRequestReturnCacheDataElseLoad// 有缓存就用缓存,未有缓存就再次央浼

NSURLRequestReturnCacheDataDontLoad//
有缓存就用缓存,未有缓存就不发央浼,当做央求出错管理(用于离线方式)

NSURLRequestReloadRevalidatingCacheData // 未实现

6.缓存的注意事项

缓存的设置要求基于具体的气象考虑,如果哀告某些U中华VL的归来数据:

(1)日常更新:无法用缓存!比方股票(stock)、彩票的数量据

(2)萧规曹随:果决用缓存

(3)一时更新:能够定时改换缓存战略 恐怕 清除缓存

提拔:假如大气采纳缓存,会越积越大,提议定时清除缓存

不难示例:

亚洲必赢手机入口 6

原来的文章地址:http://blog.originate.com/blog/2014/02/20/afimagecache-vs-nsurlcache/

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图