iOS中WKWebView的一些特殊使用总结

2025-05-29 0 96

前言

现在大部分的app只支持ios8以上的系统了,在接入h5时可以只管最新的wkwebview了。

wkwebview的优势

  • 性能高,稳定性好,占用的内存比较小,
  • 支持js交互
  • 支持html5 新特性
  • 可以添加进度条(然并卵,不好用,还是习惯第三方的)。
  • 支持内建手势,
  • 据说高达60fps的刷新频率(不卡)

本文将给大家总结下ios中wkwebview的一些特殊使用,下面话不多说了,来一起看看详细的介绍吧

wkwebview 加载本地网页的方式

1.直接加载字符串

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18
- (void)loadhtmlstring {

//直接加载字符串

nsstring *path = [[nsbundle mainbundle] pathforresource:@"story" oftype:nil];

nsstring *body = [nsstring stringwithcontentsofurl:[nsurl fileurlwithpath:path] encoding:(nsutf8stringencoding) error:nil];

nsstring *csspath = [[nsbundle mainbundle] pathforresource:@"css" oftype:nil];

nsstring *css = [nsstring stringwithcontentsofurl:[nsurl fileurlwithpath:csspath] encoding:nsutf8stringencoding error:nil];

nsstring *html = @"<html>";

html = [html stringbyappendingstring:@"<head>"];

html = [html stringbyappendingstring:@"<meta name=\\"viewport\\" content=\\"width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no,viewport-fit=cover\\">"];

html = [html stringbyappendingstring:@"<style type=\\"text/css\\">"];

html = [html stringbyappendingstring:css];

html = [html stringbyappendingstring:@"</style></head><body>"];

html = [html stringbyappendingstring:body];

html = [html stringbyappendingstring:@"</body></html>"];

[webview loadhtmlstring:html baseurl:nil];

}

需要注意的是, baseurl 可以用来控制请求权限

2.加载本地文件

?

1

2

3

4

5

6

7

8

9

10

11

12

13
- (void)loadhtmlcontent {

//加载本地文件

nsstring *rootpath = [nshomedirectory() stringbyappendingpathcomponent:@"documents"];

nsurl *rooturl = [nsurl fileurlwithpath:rootpath];

nsstring *bodytargetpath = [rootpath stringbyappendingpathcomponent:@"index.html"];

nsurl *url = [nsurl fileurlwithpath:bodytargetpath];

//这里必须指定到沙盒的具体文件夹,不能再沙盒根目录上

[webview loadfileurl:url allowingreadaccesstourl:rooturl];

}

重定向请求

1.通过 urlprotocol

新建 protocol 的子类,并添加请求属性

?

1
@property (nonnull,strong) nsurlsessiondatatask *task;

由于 wkwebview 的特殊性,这里需要新建类别,并注册需要监听的请求头 [nsurlprotocol wk_registerscheme:@"http"];

注册监听 [nsurlprotocol registerclass:[bzurlprotocol class]];

过滤需要进行处理的请求,同时也要过滤那些已经处理过的请求。

?

1

2

3

4

5

6

7

8

9

10
+ (bool)caninitwithrequest:(nsurlrequest *)request {

if ([request.url.absolutestring containsstring:@"localhost"]) {

//看看是否已经处理过了,防止无限循环

if ([nsurlprotocol propertyforkey:kbzurlprotocolkey inrequest:request]) {

return no;

}

return yes;

}

return no;

}

将请求通过下面的方法,进行重新组装,设置成我们自己的请求

?

1
+ (nsurlrequest *)canonicalrequestforrequest:(nsurlrequest *)request

将上面组装好的请求,通过下面的方法发出。并在这里将发出的请求,进行标记,因为会重走流程,避免循环处理

?

1

2

3

4

5

6

7

8

9
- (void)startloading {

nsmutableurlrequest *mutablereqeust = [[self request] mutablecopy];

//给我们处理过的请求设置一个标识符, 防止无限循环,

[nsurlprotocol setproperty:@yes forkey:kbzurlprotocolkey inrequest:mutablereqeust];

nsurlsession *session = [nsurlsession sessionwithconfiguration:[nsurlsessionconfiguration defaultsessionconfiguration] delegate:self delegatequeue:nil];

self.task = [session datataskwithrequest:self.request];

[self.task resume];

}

这里通过 task 来进行网络请求发送,也可以在这里进行请求的缓存处理,加快访问

最后需要设置代理方法,保证请求被允许和接收到数据后的加载

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16
- (void)urlsession:(nsurlsession *)session

datatask:(nsurlsessiondatatask *)datatask

didreceiveresponse:(nsurlresponse *)response

completionhandler:(void (^)(nsurlsessionresponsedisposition))completionhandler {

//允许请求加载

[[self client] urlprotocol:self didreceiveresponse:response cachestoragepolicy:nsurlcachestorageallowed];

completionhandler(nsurlsessionresponseallow);

}

- (void)urlsession:(nsurlsession *)session

datatask:(nsurlsessiondatatask *)datatask

didreceivedata:(nsdata *)data {

//加载数据

[[self client] urlprotocol:self didloaddata:data];

}

停止请求的时候注意销毁对象

?

1

2

3

4

5
- (void)stoploading {

if (self.task != nil) {

[self.task cancel];

}

}

退出的时候也要注意移除监听

?

1

2
[nsurlprotocol wk_unregisterscheme:@"http"];

[nsurlprotocol unregisterclass:[bzurlprotocol class]];

2.通过第三方库 gcdwebserver 处理请求

建立 server 要在发出请求之前

?

1
server = [[gcdwebserver alloc] init];

添加监控方法,这里提供了很多种选择,包含了请求方式和异步同步回调等,这里选择了 get 方法和异步回调。拿到结果后将其回调给 server ,完成重定向

?

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
//异步请求函数

[server adddefaulthandlerformethod:@"get"

requestclass:[gcdwebserverrequest class]

asyncprocessblock:^(__kindof gcdwebserverrequest * _nonnull request, gcdwebservercompletionblock _nonnull completionblock) {

if ([request.url.absolutestring containsstring:@"localhost"]) {

//命中了需要特殊处理的请求,这里进行特定操作

nsurl *url = [nsurl urlwithstring:@"http://m.baidu.com/static/search/baiduapp_icon.png"];

nsurlrequest *request = [nsurlrequest requestwithurl:url];

nsurlsession *session = [nsurlsession sharedsession];

//发出请求

nsurlsessiondatatask *task = [session datataskwithrequest:request completionhandler:^(nsdata * _nullable data, nsurlresponse * _nullable response, nserror * _nullable error) {

if (data && error == nil) {

//接收到正确的数据,并返回给server

gcdwebserverdataresponse *response = [gcdwebserverdataresponse responsewithdata:data contenttype:@"image/jpeg"];

completionblock(response);

} else {

//数据请求失败,返回给server一个空的或者失败的结果

gcdwebserverdataresponse *response = [gcdwebserverdataresponse response];

completionblock(response);

}

}];

[task resume];

}

}];

开启 server [server start];

最后是发出请求,否则会发生监控不生效的问题

iOS中WKWebView的一些特殊使用总结iOS中WKWebView的一些特殊使用总结

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对快网idc的支持。

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 iOS中WKWebView的一些特殊使用总结 https://www.kuaiidc.com/89111.html

相关文章

发表评论
暂无评论