当前位置:首页 » 文件管理 » iosuiwebview缓存

iosuiwebview缓存

发布时间: 2022-09-07 17:23:05

Ⅰ 如何实现 javascript “同步”调用 app 代码

在 App 混合开发中,app 层向 js 层提供接口有两种方式,一种是同步接口,一种一异步接口(不清楚什么是同步的请看这里的讨论)。为了保证 web 流畅,大部分时候,我们应该使用异步接口,但是某些情况下,我们可能更需要同步接口。同步接口的好处在于,首先 js 可以通过返回值得到执行结果;其次,在混合式开发中,app 层导出的某些 api 按照语义就应该是同步的,否则会很奇怪——一个可能在 for 循环中使用的,执行非常快的接口,比如读写某个配置项,设计成异步会很奇怪。
那么如何向 js 层导出同步接口呢?
我们知道,在 Android 框架中,通过 WebView.addJavascriptInterface() 这个函数,可以将 java 接口导出到 js 层,并且这样导出的接口是同步接口。但是在 iOS 的 Cocoa 框架中,想导出同步接口却不容易,究其原因,是因为 UIWebView 和 WKWebView 没有 addJavascriptInterface 这样的功能。同时,Android 这个功能爆出过安全漏洞,那么,我们有没有别的方式实现同步调用呢?我们以 iOS UIWebView 为例提供一种实现,WKWebView 和 Android 也可以参考。
为了找到问题的关键,我们看一下 iOS 中实现 js 调用 app 的通行方法:
首先,自定义 UIWebViewDelegate,在函数 shouldStartLoadWithRequest:navigationType: 中拦截请求。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

- (BOOL) webView:(UIWebView* _Nonnull)webView
shouldStartLoadWithRequest:(NSURLRequest* _Nonnull)request
navigationType:(UIWebViewNavigationType)navigationType {
if ([request.HTTPMethod compare:@"GET" options:NSCaseInsensitiveSearch] != NSOrderedSame) {
// 不处理非 get 请求
return YES;
}

NSURL* url = request.URL;

if ([url.scheme isEqualToString:@'YourCustomProtocol']) {
return [self onMyRequest:request];
}

return YES;
}

这种做法实质上就是将函数调用命令转化为 url,通过请求的方式通知 app 层,其中 onMyRequest: 是自定义的 request 响应函数。为了发送请求,js 层要建立一个隐藏的 iframe 元素,每次发送请求时修改 iframe 元素的 src 属性,app 即可拦截到相应请求。

1
2
3
4
5
6
7
8
9
10
11
12
13

/**
* js 向 native 传递消息
* @method js_sendMessageToNativeAsync
* @memberof JSToNativeIOSPolyfill
* @public
* @param str {String} 消息字符串,由 HybridMessage 转换而来
*/
JSToNativeIOSPolyfill.prototype.js_sendMessageToNativeAsync = function (str) {
if (!this.ifr_) {
this._prepareIfr();
}

this.ifr_.src = 'YourCustomProtocol://__message_send__?msg=' + encodeURIComponent(str); }

当 app 执行完 js 调用的功能,执行结果无法直接返回,为了返回结果,普遍采用回调函数方式——js 层记录一个 callback,app 通过 UIWebView 的 函数调用这个 callback(类似 jsonp 的机制)。
注意,这样封装的接口,天然是异步接口。因为 js_sendMessageToNativeAsync 这个函数会立即返回,不会等到执行结果发回来。
所以,我们要想办法把 js 代码“阻塞”住。
请回忆一下,js 中是用什么方法能把 UI 线程代码“阻塞”住,同时又不跑满 CPU?

1
2
3
4

var async = false;
var url = 'http://.com';
var method = 'GET';<br>var req = new XMLHttpRequest();<br>
req.open(method, url, async);<br>req.send(null);

“同步”ajax(其实没这个词,ajax 内涵异步的意思)可以!在 的响应没返回之前,这段代码会一直阻塞。一般来说同步请求是不允许使用的,有导致 UI 卡顿的风险。但是在这里因为我们并不会真的去远端请求内容,所以不妨一用。
至此实现方式已经比较清楚了,梳理一下思路:
使用同步 XMLHttpRequest 配合特殊构造的 URL 通知 app层。
app 层拦截请求执行功能,将结果作为 Response 返回。
XMLHttpRequest.send() 返回,通过 status 和 responseText 得到结果。
那么,如何拦截请求呢?大家知道,UIWebViewDelegate 是不会拦截 XMLHttpRequest 请求的,但是 iOS 至少给了我们两个位置拦截这类请求——NSURLCache 和 NSURLProtocol。
一、NSURLCache 是 iOS 中用来实现自定义缓存的类,当你创建了自定义的 NSURLCache 子类对象,并将其设置为全局缓存管理器,所有的请求都会先到这里检查有无缓存(如果你没禁掉缓存的话)。我们可以借助这个性质拦截到接口调用请求,执行并返回数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

- (NSCachedURLResponse*) cachedResponseForRequest:(NSURLRequest *)request {
if ([request.HTTPMethod compare:@"GET" options:NSCaseInsensitiveSearch] != NSOrderedSame) {
// 只对 get 请求做自定义处理
return [super cachedResponseForRequest:request];
}

NSURL* url = request.URL;
NSString* path = url.path;
NSString* query = url.query;

if (path == nil || query == nil) {
return [super cachedResponseForRequest:request];
}

LOGF(@"url = %@, path = %@, query = %@", url, path, query);

if ([path isEqualToString:@"__env_get__"]) {
// 读环境变量
return [self getEnvValueByURL:url]; //*
} else if ([path isEqualToString:@"__env_set__"]) {
// 写环境变量
return [self setEnvValueByURL:url];
}

return [super cachedResponseForRequest:request];
}

注意注释有 * 号的一行,即是执行 app 接口,返回结果。这里的结果是一个 NSCachedResponse 对象,就不赘述了。

Ⅱ ios uiwebview 是异步加载吗

不是的,uiwebview是同步加载的。
UIWebView是IOS内置的浏览器,可以浏览网页,打开文档 html/htm pdf docx txt等格式的文件。 safari浏览器就是通过UIWebView做的。
服务器将MIME的标识符等放入传送的数据中告诉浏览器使用那种插件读取相关文件。
uiwebview加载各种本地文件:
- (void)viewDidLoad
{
[super viewDidLoad];
[self setupUI];

NSString *path = [[NSBundle mainBundle] pathForResource:@"关于.docx" ofType:nil];
NSURL *url = [NSURL fileURLWithPath:path];
NSLog(@"%@", [self mimeType:url]);

//webview加载本地文件,可以使用加载数据的方式
//第一个诶参数是一个NSData, 本地文件对应的数据
//第二个参数是MIMEType
//第三个参数是编码格式
//相对地址,一般加载本地文件不使用,可以在指定的baseURL中查找相关文件。

//以二进制数据的形式加载沙箱中的文件,
NSData *data = [NSData dataWithContentsOfFile:path];

[self.webView loadData:data MIMEType:@"application/vnd.openxmlformats-officedocument.wordprocessingml.document" textEncodingName:@"UTF-8" baseURL:nil];
}

#pragma mark 加载docx文件
- (void)loadDOCX
{

NSString *path = [[NSBundle mainBundle] pathForResource:@"关于.docx" ofType:nil];
NSURL *url = [NSURL fileURLWithPath:path];
NSLog(@"%@", [self mimeType:url]);

NSData *data = [NSData dataWithContentsOfFile:path];

[self.webView loadData:data MIMEType:@"application/vnd.openxmlformats-officedocument.wordprocessingml.document" textEncodingName:@"UTF-8" baseURL:nil];}

#pragma mark 加载pdf文件
- (void)loadPDF
{
NSString *path = [[NSBundle mainBundle] pathForResource:@"iOS6Cookbook.pdf" ofType:nil];
NSURL *url = [NSURL fileURLWithPath:path];
NSLog(@"%@", [self mimeType:url]);

NSData *data = [NSData dataWithContentsOfFile:path];

[self.webView loadData:data MIMEType:@"application/pdf" textEncodingName:@"UTF-8" baseURL:nil];
}

#pragma mark 加载本地文本文件
- (void)loadText
{
NSString *path = [[NSBundle mainBundle] pathForResource:@"关于.txt" ofType:nil];
NSURL *url = [NSURL fileURLWithPath:path];
NSLog(@"%@", [self mimeType:url]);

NSData *data = [NSData dataWithContentsOfFile:path];

[self.webView loadData:data MIMEType:@"text/plain" textEncodingName:@"UTF-8" baseURL:nil];
}

#pragma mark 加载本地html文件
- (void)loadHTML
{
NSString *path = [[NSBundle mainBundle] pathForResource:@"demo.html" ofType:nil];
NSURL *url = [NSURL fileURLWithPath:path];
NSLog(@"%@", [self mimeType:url]);

NSData *data = [NSData dataWithContentsOfFile:path];

[self.webView loadData:data MIMEType:@"text/html" textEncodingName:@"UTF-8" baseURL:nil];
}

#pragma mark 获取指定URL的MIMEType类型
- (NSString *)mimeType:(NSURL *)url
{
//1NSURLRequest
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//2NSURLConnection

//3 在NSURLResponse里,服务器告诉浏览器用什么方式打开文件。

//使用同步方法后去MIMEType
NSURLResponse *response = nil;
[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
return response.MIMEType;
}

Ⅲ ios wkwebview 是否有缓存

1:获取webviewscrovllviewcontentsize进行设置

-(void)webViewDidFinishLoad:(UIWebView

*)webView{

CGFloat

webViewHeight=[webView.scrollView

contentSize].height;

CGRect

newFrame
=
webView.frame;

newFrame.size.height

=
webViewHeight;

webView.frame

=
newFrame;

}

2:执行js语句 直接获取html文档dom高度

-(void)webViewDidFinishLoad:(UIWebView

*)webView{

CGFloat

webViewHeight=

[[webView

:

@"document.body.offsetHeight"]floatValue];

// CGFloat webViewHeight= [[webView
:
@"document.body.scrollHeight"]floatValue];

CGRect

newFrame
=
webView.frame;

newFrame.size.height

=
webViewHeight;

webView.frame

=
newFrame;

}

3.先UIWebView高度设再使用sizeThatFits返刚合适

-(void)webViewDidFinishLoad:(UIWebView

*)webView{

CGSize

actualSize
=
[webView

sizeThatFits:CGSizeZero];

CGRect

newFrame
=
webView.frame;

newFrame.size.height

=
actualSize.height;

webView.frame

=
newFrame;

}

4.遍历webview视图 获取UIWebDocumentView高度即实际高度
Objective-C

-(void)webViewDidFinishLoad:(UIWebView

*)webView{

CGFloat
webViewHeight
=
0.0f;

if
([webView.subviews

count]

>
0)

{

UIView
*scrollerView
=
webView.subviews[0];

if
([scrollerView.subviews

count]

>
0)

{

UIView
*webDocView
=
scrollerView.subviews.lastObject;

if
([webDocView

isKindOfClass:[NSClassFromString(@"UIWebDocumentView")

class]])

{

webViewHeight
=
webDocView.frame.size.height;//获取文档高度

webView.frame=

webDocView.frame;

//更新UIWebView 高度

}

}

}

}

Ⅳ ios uiwebview 缓存文件在哪

顺便说下NSURLRequest对象,它有个cachePolicy属性,只要其值为的话,就不会访问缓存。可喜的是这种情况貌似只有在缓存里没取到,或是强制刷新时才可能出现。
实际上NSURLCache本身就有磁盘缓存功能,然而在iOS上,NSCachedURLResponse却被限制为不能缓存到磁盘(NSURLCacheStorageAllowed被视为)。
不过既然知道了原理,那么只要自己实现一个NSURLCache的子类,然后改写cachedResponseForRequest:方法,让它从硬盘读取缓存即可。

于是就开工吧。这次的demo逻辑比较复杂,因此我就按步骤来说明了。

先定义视图和控制器。
它的逻辑是打开应用时就尝试访问缓存文件,如果发现存在,则显示缓存完毕;否则就尝试下载整个网页的资源;在下载完成后,也显示缓存完毕。
不过下载所有资源需要解析HTML,甚至是JavaScript和CSS。为了简化我就直接用一个不显示的UIWebView载入这个页面,让它自动去发起所有请求。
当然,缓存完了还需要触发事件来显示网页。于是再提供一个按钮,点击时显示缓存的网页,再次点击就关闭。
顺带一提,我本来想用Google为例的,可惜它自己实现了HTML 5离线浏览,也就体现不出这种方法的意义了,于是只好拿网络来垫背。
Objective-c代码 收藏代码
#import <UIKit/UIKit.h>

@interface WebViewController : UIViewController <UIWebViewDelegate> {
UIWebView *web;
UILabel *label;
}

@property (nonatomic, retain) UIWebView *web;
@property (nonatomic, retain) UILabel *label;

- (IBAction)click;

@end

#import "WebViewController.h"
#import "URLCache.h"

@implementation WebViewController

@synthesize web, label;

- (IBAction)click {
if (web) {
[web removeFromSuperview];
self.web = nil;
} else {
CGRect frame = {{0, 0}, {320, 380}};
UIWebView *webview = [[UIWebView alloc] initWithFrame:frame];
webview.scalesPageToFit = YES;
self.web = webview;

NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www..com/"]];
[webview loadRequest:request];
[self.view addSubview:webview];
[webview release];
}
}

- (void)addButton {
CGRect frame = {{130, 400}, {60, 30}};
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = frame;
[button addTarget:self action:@selector(click) forControlEvents:UIControlEventTouchUpInside];
[button setTitle:@"我点" forState:UIControlStateNormal];
[self.view addSubview:button];
}

- (void)viewDidLoad {
[super viewDidLoad];

URLCache *sharedCache = [[URLCache alloc] initWithMemoryCapacity:1024 * 1024 diskCapacity:0 diskPath:nil];
[NSURLCache setSharedURLCache:sharedCache];

CGRect frame = {{60, 200}, {200, 30}};
UILabel *textLabel = [[UILabel alloc] initWithFrame:frame];
textLabel.textAlignment = UITextAlignmentCenter;
[self.view addSubview:textLabel];
self.label = textLabel;

if (![sharedCache.responsesInfo count]) { // not cached
textLabel.text = @"缓存中…";

CGRect frame = {{0, 0}, {320, 380}};
UIWebView *webview = [[UIWebView alloc] initWithFrame:frame];
webview.delegate = self;
self.web = webview;

NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www..com/"]];
[webview loadRequest:request];
[webview release];
} else {
textLabel.text = @"已从硬盘读取缓存";
[self addButton];
}

[sharedCache release];
}

- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
self.web = nil;
label.text = @"请接通网络再运行本应用";
}

- (void)webViewDidFinishLoad:(UIWebView *)webView {
self.web = nil;
label.text = @"缓存完毕";
[self addButton];

URLCache *sharedCache = (URLCache *)[NSURLCache sharedURLCache];
[sharedCache saveInfo];
}

- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];

if (!web) {
URLCache *sharedCache = (URLCache *)[NSURLCache sharedURLCache];
[sharedCache removeAllCachedResponses];
}
}

- (void)viewDidUnload {
self.web = nil;
self.label = nil;
}

- (void)dealloc {
[super dealloc];
[web release];
[label release];
}

@end

Ⅳ ios webview 用RNCachingURLProtocol缓存,怎么清理缓存

//清除UIWebView的缓存
[[NSURLCachesharedURLCache] removeAllCachedResponses];
试试

Ⅵ 如何改进iOS App的离线使用体验

打开过的文章、下载过的音频、查看过的图片我们都希望Cache到本地,下次不用再向服务器请求。

首先,我们为了最快让用户看到内容,会在ViewDidLoad加载Cache数据,如:

- (void)viewDidLoad {

[self getArticleList:0 length:SECTION_LENGTH useCacheFirst:YES];
}

然后在viewDidAppear中向服务器请求最新数据,如

- (void)viewDidAppear:(BOOL)animated {

[super viewDidAppear:animated];

//...

[self getArticleList:0 length:SECTION_LENGTH useCacheFirst:NO]
}

当然这里的getArticleList接口有useCacheFirst参数,我们需要网络请求模块能够支持这一点,下面就介绍这些库和工具。
(借助一些工具很容易能做到这些,而不用自己造轮子。遵循“凡事都应该最简单,而不过于简陋”的原则,这里整理一下,方便项目中使用)。

1.NSMutableURLRequest

Sample(参考麒麟的文章《iOS开发之缓存(一):内存缓存》来使用NSURLCache):

NSString *paramURLAsString= @"http://www..com/";
if ([paramURLAsString length] == 0){
NSLog(@"Nil or empty URL is given");
return;
}
NSURLCache *urlCache = [NSURLCache sharedURLCache];
/* 设置缓存的大小为1M*/
[urlCache setMemoryCapacity:1*1024*1024];
//创建一个nsurl
NSURL *url = [NSURL URLWithString:paramURLAsString];
//创建一个请求
NSMutableURLRequest *request =
[NSMutableURLRequest
requestWithURL:url
cachePolicy:
timeoutInterval:60.0f];
//从请求中获取缓存输出
NSCachedURLResponse *response =
[urlCache cachedResponseForRequest:request];
//判断是否有缓存
if (response != nil){
NSLog(@"如果有缓存输出,从缓存中获取数据");
[request setCachePolicy:];
}
self.connection = nil;
/* 创建NSURLConnection*/
NSURLConnection *newConnection =
[[NSURLConnection alloc] initWithRequest:request
delegate:self
startImmediately:YES];
self.connection = newConnection;
[newConnection release];

但是NSMutableURLRequest使用起来不够简便,在实际项目中我很少用它,而基本使用ASIHTTPRequest来代替。

2.ASIHTTPRequest

你可以从这里找到它的介绍:http://allseeing-i.com/ASIHTTPRequest/,在5.0/4.0及之前iOS版本,ASIHTTPRequest基本是主力的 HTTP requests library,它本身也是Github中的开源项目,但是从iOS 5.0之后逐渐停止维护了。未来的项目可以使用AFNetworking或者MKNetworkKit代替ASIHTTPRequest。

ASIHTTPRequest的简介如下:

ASIHTTPRequest is an easy to use wrapper around the CFNetwork API
that makes some of the more tedious aspects of communicating with web
servers easier. It is written in Objective-C and works in both Mac OS X
and iPhone applications.

It is suitable performing basic HTTP requests and interacting with
REST-based services (GET / POST / PUT / DELETE). The included
ASIFormDataRequest subclass makes it easy to submit POST data and files
usingmultipart/form-data.

ASIHTTPRequest库API设计的简单易用,并且支持block、queue、gzip等丰富的功能,这是该开源项目如此受欢迎的主要原因。

ASIHTTPRequest库中提供了ASIWebPageRequest组件用于请求网页,并且能把网页中的外部资源一并请求下来,但是我在实际项目中使用后发现有严重Bug,所以不建议使用。

ASIHTTPRequest库的介绍中也提到了它可以支持REST-based service,但是与Restfull API打交道我们往往使用下面介绍的的RestKit。

Sample:

NSMutableString *requestedUrl = [[NSMutableString alloc] initWithString:self.url];

//如果优先使用本地数据
ASICachePolicy policy = _useCacheFirst ?
: ( | );

asiRequest = [ASIHTTPRequest requestWithURL:
[NSURL URLWithString:[requestedUrl :NSUTF8StringEncoding]]];

[asiRequest setDownloadCache:[ASIDownloadCache sharedCache]];
[asiRequest setCachePolicy:policy];
[asiRequest setCacheStoragePolicy:];

// Connection
if (_connectionType == ConnectionTypeAsynchronously) {

[asiRequest setDelegate:self];
[asiRequest startAsynchronous];

// Tell we're receiving.
if (!_canceled && [_delegate respondsToSelector:@selector(downloaderDidStart:)])
[_delegate downloaderDidStart:self];
}
else
{
[asiRequest startSynchronous];

NSError *error = [asiRequest error];

if (!error)
{
[self requestFinished:asiRequest];
}
else
{
[self requestFailed:asiRequest];
}
}

[requestedUrl release];

3.RestKit

官方网站:http://restkit.org/,Github开源项目,与 Restfull API 的 Web服务打交道,这个库非常便捷,它也提供了很完整的Cache机制。

Sample:

+ (void)setCachePolicy:(BOOL)useCacheFirst
{
RKObjectManager* objectManager = [RKObjectManager sharedManager];

if (useCacheFirst) {
objectManager.client.cachePolicy = RKRequestCachePolicyEnabled; //使用本地Cache,如果没有Cache请求服务器
}
else
{
objectManager.client.cachePolicy = |RKRequestCachePolicyTimeout; //离线或者超时时使用本地Cache
}
}

+ (BOOL)getHomeTimeline:(NSInteger)maxId
length:(NSInteger)length
delegate:(id<RKObjectLoaderDelegate>)delegate
useCacheFirst:(BOOL)useCacheFirst
{
if (delegate == nil)
return NO;

[iKnowAPI setCachePolicy:useCacheFirst];

//...
}

Cache请求只是RestKit最基本的功能,RestKit真正强大的地方在于处理与RESTful web services交互时的相关工作非常简便(https://github.com/RestKit/RestKit/wiki),RestKit还可以Cache data model到Core Data中:

Core Data support. Building on top of the object mapping layer,
RestKit provides integration with Apple's Core Data framework. This
support allows RestKit to persist remotely loaded objects directly back
into a local store, either as a fast local cache or a primary data store
that is periodically synced with the cloud. RestKit can populate Core
Data associations for you, allowing natural property based traversal of
your data model. It also provides a nice API on top of the Core Data
primitives that simplifies configuration and querying use cases through
an implementation of the Active Record access pattern.

但实际上RKRequestCachePolicy已经解决了大部分Cache需求。

4.SDWebImage

SDWebImage是Github开源项目:https://github.com/rs/SDWebImage,它用于方便的请求、Cache网络图片,并且请求完毕后交由UIImageView显示。

Asynchronous image downloader with cache support with an UIImageView category.

SDWebImage作为UIImageView的一个Category提供的,所以使用起来非常简单:

// Here we use the new provided setImageWithURL: method to load the web image
[imageView setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"]
placeholderImage:[UIImage imageNamed:@"placeholder.png"]];

AFNetworking也提供了类似功能(UIImageView+AFNetworking):

UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 100.0f, 100.0f)];
[imageView setImageWithURL:[NSURL URLWithString:@"http://i.imgur.com/r4uwx.jpg"] placeholderImage:[UIImage imageNamed:@"placeholder-avatar"]];

5.UIWebView中的图片Cache

如果你使用UIWebView来展示内容,在离线情况下如果也想能显示的话需要实现2点:

Cache Html页面
Cache 图片等元素

使用上面介绍的网络组件来Cache Html页面比较便捷,之后使用webView
loadHTMLString即可加载本地Html页面,而Cache图片需要更换NSURLCache公共实例为自定义的
NSURLCache(UIWebView使用的即是+[NSURLCache sharedURLCache]):

//设置使用自定义Cache机制
LocalSubstitutionCache *cache = [[[LocalSubstitutionCache alloc] init] autorelease];
[cache setMemoryCapacity:4 * 1024 * 1024];
[cache setDiskCapacity:10 * 1024 * 1024];
[NSURLCache setSharedURLCache:cache];

自定义NSURLCache:

#import <Foundation/Foundation.h>

@interface LocalSubstitutionCache : NSURLCache
{
NSMutableDictionary *cachedResponses;
}

+ (NSString *)pathForURL:(NSURL*)url;

@end

Ⅶ wkwebview后退会使用缓存吗

wkwebview后退会使用缓存
WKWebView相对于UIWebView强大了很多,内存的消耗相对少了,所提供的接口也丰富了。
navigationDelegate
[objc] view plain print?
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation { // 类似UIWebView的 -webViewDidStartLoad:
NSLog(@"didStartProvisionalNavigation");
[UIApplication sharedApplication]. = YES;
}

- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation {
NSLog(@"didCommitNavigation");
}

Ⅷ uiwebView有缓存吗

1.HTML5 , Manifest
最开始我的想法是使用HTML5中的离线存储功能,也就是分析Manifest文件来存储和更新部分资源文件。但是经过实践发现,UIWebView根本不支持HTML5,他只实现了Webkit中页面渲染的那一部分。所以要实现缓存必须要另辟蹊径。

2.NSURLCache
尽管在官方的说明文档里面说到NSURLCache和NSCachedURLResponse可以用于缓存,但经我测试好像仅仅只能用于加载本地某些资源文件(这里有一篇博客,原文是英文的,这是翻译过来的)
,而且还有大小的限制(好像根据iphone的版本不同而不同,最小是25KB吧),比如图片和JS代码, 而对于整体的页面无法进行加载。而且经过测试也没有感觉加载速度有明显的提高,我用的缓存策略是(可能是没有读取本地的缓存文件?),离线模式下也无法加载(可能是baseURL的关系?)。
这找到一篇博客,一种新的解决思路,经过我测试,可以很好的实现缓存。
另外做一点引申,对于动态获取数据的页面,我们不需要缓存的那些请求,只要过滤掉就可以了。
先新建一个文件,把所有不需要缓存的请求的URL写在一个文件里,就象HTML5的 Cache Manifest那样。
然后需要使用缓存的时候读取这个文件,并在重写的- (NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request 这个方法内对请求进行判断,如果是属于这个文件内的,比如web service的请求就直接返回,其他的就继续处理。

3.ASIHTTPRequest,ASIDownloadCache 和 ASIWebPageRequest
首先我得说,这确实是个很好的框架,使用起来确实很方便,但是对于缓存这个问题,好像也跟第二点提到的效果差不多,加载速度没有明显的提升,离线模式下也无法加载。

Ⅸ ios ios 怎么获取uiwebview的指定标签的img

let path = NSBundle.mainBundle().pathForResource("test", ofType: "html")
let url = NSURL(fileURLWithPath: path!)

do {
let html = try String(contentsOfURL: url, encoding: NSUTF8StringEncoding)
// print(html)

// 获取所有img src中的src链接,并将src更改名称
// 这里直接采用同步获取数据,异步也是一样的道理,为了方便写demo,仅以同步加载图片为例。
// 另外,这不考虑清除缓存的问题。
do {
let regex = try NSRegularExpression(pattern: "<img\\ssrc[^>]*/>", options: .AllowCommentsAndWhitespace)

let result = regex.matchesInString(html, options: .ReportCompletion, range: NSMakeRange(0, html.characters.count))

var content = html as NSString
var sourceSrcs: [String: String] = ["": ""]

for item in result {
let range = item.rangeAtIndex(0)

let imgHtml = content.substringWithRange(range) as NSString
var array = [""]

if imgHtml.rangeOfString("src=\"").location != NSNotFound {
array = imgHtml.componentsSeparatedByString("src=\"")
} else if imgHtml.rangeOfString("src=").location != NSNotFound {
array = imgHtml.componentsSeparatedByString("src=")
}

if array.count >= 2 {
var src = array[1] as NSString
if src.rangeOfString("\"").location != NSNotFound {
src = src.substringToIndex(src.rangeOfString("\"").location)

// 图片链接正确解析出来
print(src)

// 加载图片
// 这里不处理重复加载的问题,实际开发中,应该要做一下处理。
// 也就是先判断是否已经加载过,且未清理掉该缓存的图片。如果
// 已经缓存过,否则才执行下面的语句。
let data = NSData(contentsOfURL: NSURL(string: src as String)!)
let localUrl = self.saveImageData(data!, name: (src as String).md5)

// 记录下原URL和本地URL
// 如果用异步加载图片的方式,先可以提交将每个URL起好名字,由于这里使用的是原URL的md5作为名称,
// 因此每个URL的名字是固定的。
sourceSrcs[src as String] = localUrl
}
}
}

for (src, localUrl) in sourceSrcs {
if !localUrl.isEmpty {
content = content.(src as String, withString: localUrl, options: NSStringCompareOptions.LiteralSearch, range: NSMakeRange(0, content.length))
}
}

print(content as String)
webView.loadHTMLString(content as String, baseURL: url)
} catch {
print("match error")
}
} catch {
print("load html error")
}

热点内容
pr编译影片出错无法生成帧 发布:2024-10-11 23:21:51 浏览:731
c语言读取txt文件到数组中 发布:2024-10-11 23:21:16 浏览:348
iosspeex编译 发布:2024-10-11 23:11:39 浏览:740
用户映射sqlserver 发布:2024-10-11 23:09:09 浏览:307
单机传奇充值脚本 发布:2024-10-11 22:18:38 浏览:172
qt播放器源码下载 发布:2024-10-11 22:13:35 浏览:741
安卓手游怎么付费 发布:2024-10-11 22:06:17 浏览:264
t77买哪个配置好 发布:2024-10-11 21:40:31 浏览:937
照片压缩美图秀秀 发布:2024-10-11 21:23:42 浏览:418
冠状病毒加密 发布:2024-10-11 21:09:21 浏览:105