欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

简单说说iOS之WKWebView的用法小结

程序员文章站 2022-10-15 18:38:24
wkwebview的优势 性能高,稳定性好,占用的内存比较小, 支持js交互 支持html5 新特性 可以添加进度条(然并卵,不好用,还是习...

wkwebview的优势

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

1.xcode新建my.html文件,自定义html内容,主要代码如下:

(1)标签为ui样式(写了简单的js代码,目的用于讲解交互)

(2)onclick为js事件,当js想给oc传递参数时,采用如下代码:window.webkit.messagehandlers.<方法名>.postmessage(数据)

<h1 style="text-align:center;background-color: #e6b500;wdith:100px;height:40px">欢迎来到js世界</h1>

 <p style="text-align:center"> <a href="github://callname_?https://github.com/wslcmk" rel="external nofollow" >github主页</a> :截获url调用oc</p>

<p style="text-align:center"> <a href="http://192.168.0.116/monkey/ios-urnetworking/commits/master" rel="external nofollow" >gitlab主页</a> </p>
<p style="text-align:center"> <button id="btn1" type = "button" onclick = "jstoocfunctionone()" > js调用oc->不带参数 </button> </p>

<p style="text-align:center"> <button id="btn2" type = "button" onclick = "jstoocfunctiontwo()"> js调用oc->带参数 </button> </p>


<p style="text-align:center"> <button id="btn3" type = "button" onclick = "showalert()" > oc捕获到html的弹出框 </button> </p>

<!--    js语法-->
<script type = "text/javascript">
  
function jstoocfunctionone()
{
  window.webkit.messagehandlers.jstoocnoprams.postmessage({});
}

function jstoocfunctiontwo()
{
  window.webkit.messagehandlers.jstoocwithprams.postmessage({"params":"我是js参数"});
}

function showalert()
{
  alert("我来自js世界,被你发现了");
}

//改变背景色
function changebgcolor()
{
  document.body.style.backgroundcolor = randomcolor();
}

2.kvo实现加载进度条以及标题

//  kvo监听:获取进度并显示 获取标题并显示
  [self.webview addobserver:self forkeypath:@"estimatedprogress" options:nskeyvalueobservingoptionnew context:nil];
  [self.webview addobserver:self forkeypath:@"title" options:nskeyvalueobservingoptionnew context:nil];

#pragma mark - kvo
- (void)observevalueforkeypath:(nsstring *)keypath ofobject:(id)object change:(nsdictionary<nskeyvaluechangekey,id> *)change context:(void *)context
{
  if ([keypath isequaltostring:@"title"]&&object == _webview) {
    self.title = _webview.title;
  }else if ([keypath isequaltostring:@"estimatedprogress"]
       && object == _webview)
  {
    self.progressview.progress = _webview.estimatedprogress;
    if (_webview.estimatedprogress >= 1.0f) {
      dispatch_after(dispatch_time(dispatch_time_now, (int64_t)(1 * nsec_per_sec)),
             dispatch_get_main_queue(), ^{
               self.progressview.progress = 0;
             });
    }
  }
}

3.通过拦截url方式,js调用oc代码,决定是否跳转(wknavigationdelegate代理)

#pragma mark -- wknavigationdelegate  wknavigationdelegate主要处理一些跳转、加载处理操作
// 根据webview对于即将跳转的http请求头信息和相关信息来决定是否跳转
- (void)webview:(wkwebview *)webview decidepolicyfornavigationaction:(wknavigationaction *)navigationaction decisionhandler:(void (^)(wknavigationactionpolicy))decisionhandler {
  
  nsstring * urlstr = navigationaction.request.url.absolutestring;
  nslog(@"发送跳转请求:%@",urlstr);
  //自己定义的协议头
  nsstring *htmlheadstring = @"github://";
  if([urlstr hasprefix:htmlheadstring]){
    uialertcontroller *alertcontroller = [uialertcontroller alertcontrollerwithtitle:@"通过截取url调用oc" message:@"前往github?" preferredstyle:uialertcontrollerstylealert];
    [alertcontroller addaction:([uialertaction actionwithtitle:@"取消" style:uialertactionstylecancel handler:^(uialertaction * _nonnull action) {
      
    }])];
    [alertcontroller addaction:([uialertaction actionwithtitle:@"打开" style:uialertactionstyledefault handler:^(uialertaction * _nonnull action) {
      nsurl * url = [nsurl urlwithstring:[urlstr stringbyreplacingoccurrencesofstring:@"github://callname_?" withstring:@""]];
      [[uiapplication sharedapplication]canopenurl:url];
    }])];
    [self presentviewcontroller:alertcontroller animated:yes completion:nil];
    decisionhandler(wknavigationactionpolicycancel);
  }else{
    decisionhandler(wknavigationactionpolicyallow);
  }
}

4.oc获取js alert内容(wkuidelegate处理警告、输入、以及确认,这里只列举了alert。输入和确认就不一一列举了,分别是js端confirm和prompt函数触发)

当调用js端alert函数时:通过如下代理获取alert内容

#pragma mark -- wkuidelegate wkuidelegate主要处理js脚本,确认框,警告框等
- (void)webview:(wkwebview *)webview runjavascriptalertpanelwithmessage:(nsstring *)message initiatedbyframe:(wkframeinfo *)frame completionhandler:(void (^)(void))completionhandler {
  uialertcontroller *alertcontroller = [uialertcontroller alertcontrollerwithtitle:@"js-alert-action" message:message?:@"" preferredstyle:uialertcontrollerstylealert];
  [alertcontroller addaction:([uialertaction actionwithtitle:@"ok" style:uialertactionstyledefault handler:^(uialertaction * _nonnull action) {
    completionhandler();
  }])];
  [self presentviewcontroller:alertcontroller animated:yes completion:nil];
}

5.oc调用js代码,实现改变js页面颜色(通过evaluatejavascript函数、jsstring为js端方法名)

#pragma mark -navigationitem action
- (void)octojs
{
  // changecolor()是js方法名
  nsstring *jsstring = [nsstring stringwithformat:@"changebgcolor()"];
  [_webview evaluatejavascript:jsstring completionhandler:^(id _nullable data, nserror * _nullable error) {
    
  }];
}

6.通过接受js方法名捕捉方法(带参数和不带参数,js端向ios传递参数,采用window.webkit.messagehandlers.<方法名>.postmessage(数据))

(1)需要引入wkusercontentcontroller、主要代码如下

//创建网页配置对象
    wkwebviewconfiguration *config = [[wkwebviewconfiguration alloc] init];
    wkusercontentcontroller * wkucontroller = [[wkusercontentcontroller alloc] init];
    //注册一个name为jstoocnoprams的js方法 设置处理接收js方法的对象
    [wkucontroller addscriptmessagehandler:self name:@"jstoocnoprams"];
    [wkucontroller addscriptmessagehandler:self name:@"jstoocwithprams"];
    config.usercontentcontroller = wkucontroller;

(2)核心代码

#pragma mark - 通过接收js传出消息的name进行捕捉的回调方法
- (void)usercontentcontroller:(wkusercontentcontroller *)usercontentcontroller didreceivescriptmessage:(wkscriptmessage *)message{
  nslog(@"name:%@\\\\n body:%@\\\\n frameinfo:%@\\\\n",message.name,message.body,message.frameinfo);
  //用message.body获得js传出的参数体
  nsdictionary * parameter = message.body;
  //js调用oc
  if([message.name isequaltostring:@"jstoocnoprams"]){
    uialertcontroller *alertcontroller = [uialertcontroller alertcontrollerwithtitle:@"js调用到了oc" message:@"不带参数" preferredstyle:uialertcontrollerstylealert];
    [alertcontroller addaction:([uialertaction actionwithtitle:@"ok" style:uialertactionstyledefault handler:^(uialertaction * _nonnull action) {
    }])];
    [self presentviewcontroller:alertcontroller animated:yes completion:nil];
    
  }else if([message.name isequaltostring:@"jstoocwithprams"]){
    uialertcontroller *alertcontroller = [uialertcontroller alertcontrollerwithtitle:@"js调用到了oc" message:parameter[@"params"] preferredstyle:uialertcontrollerstylealert];
    [alertcontroller addaction:([uialertaction actionwithtitle:@"ok" style:uialertactionstyledefault handler:^(uialertaction * _nonnull action) {
    }])];
    [self presentviewcontroller:alertcontroller animated:yes completion:nil];
  }  
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。