打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Swift-WKWebView与JavaScript的细节,H5页面跳转原生界面

大家(也包括我)要学会 明白一件事情(注意断句,哈哈)。优秀的程序猿会将问题简单化。
世界上有10种人,一种是先把问题复杂化,然后在一点点的做减法;另一种是先把问题简单化,然后在慢慢的做加法;(好了该进入正题了哈哈!) 文中有源码地址
一,加载HTML的几种方式

    /**     *  1,加载网络html     */    NSString * surl = @"http://192.168.3.134:7080/toCompanyTouch";    NSURLRequest * request = [NSURLRequest requestWithURL:[NSURL URLWithString:surl]];    [self.wkwebView loadRequest:request];     /**     *  2,加载本地html 资源(内容)     */    NSURL * url =[[NSBundle mainBundle] URLForResource:@"testH5" withExtension:@"html"];    NSString *path = [[NSBundle mainBundle] pathForResource:@"testH5" ofType:@"html"];    NSString * htmlString = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];    [self.wkwebView loadHTMLString:htmlString baseURL:url];       /**     *  3,加载本地html url     */    NSURL * url2 =[[NSBundle mainBundle] URLForResource:@"testH5" withExtension:@"html"];    [self.wkwebView loadFileURL:url2 allowingReadAccessToURL:url2];
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

Native和js交互没有想象中那么不着边际
二,UIWebView与JS交互
首先使用到 <JavaScriptCore/JavaScriptCore.h>框架中的 JSContextJSExport对象。
JSContext Native和JS交互时,连接两者的上下文,
JSExport Native和JS交互协议。(实现方法调用时必须实现的协议)

然后通过KVC的方式获得 JSContext(上线时可能有风险,还可以通过KVO的方式获得)

- (void)webViewDidFinishLoad:(UIWebView *)webView{    JSContext * context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];    // self 是装有 UIWebView的控制器,并且它遵守了 JSExport 协议    //把self这个对象放到上下文中,通过VC这个key可以找到self这个对象    [context setObject:self forKeyedSubscript:@"VC"];}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在然后就可以在JS页面中使用这个VC了,VC能对应上OC中那个controller
不要忘记在UIViewController中遵守并实现JSExport

//遵守协议@protocol JS_OCCOnnectProtocolInWeb <JSExport>- (void)testLog:(NSDictionary*)dict;@end@interface UIWeb_VC () <UIWebViewDelegate,JS_OCCOnnectProtocolInWeb>@property UIWebView * webView;@end@implementation UIWeb_VC//实现协议方法- (void)testLog:(NSDictionary*)dict{    NSLog(@"---testLog--");    NSLog(@"dict=[%@]",dict);}@end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

最后在js中调用就方便了

<button onclick="VC.testLog({'page':'testVC'})">UIWeb测试</button>
  • 1

打印信息如下

2017-12-06 15:18:58.645195+0800 TestHybriod[2378:1026324] ---testLog--2017-12-06 15:18:58.646071+0800 TestHybriod[2378:1026324] dict=[{    page = testVC;}]
  • 1
  • 2
  • 3
  • 4

三,WKWebView与JS交互

1,WebKitWKWebView使用的是Safari的浏览器内核,在性能上高于UIWebView
wk的交互需要用到 MessageHandler,在实例化WKWebView时配置一下WKUserContentController,并且遵守 WKScriptMessageHandler 协议实现他的方法

- (void)viewDidLoad {    [super viewDidLoad];    WKWebViewConfiguration * config = [[WKWebViewConfiguration alloc]init];    config.userContentController =[[WKUserContentController alloc]init];    //意思是将名字为 ocWkModth 的方法注册到js中    [config.userContentController addScriptMessageHandler:self name:@"ocWkModth"];    self.wkwebView = [[WKWebView alloc]initWithFrame:self.view.boundsconfiguration:config];}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

WKScriptMessageHandler 协议的方法。在这里可以接收到js传来的参数

- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{    NSLog(@"body=[%@]",message.body);    NSLog(@"name=[%@]",message.name);    NSLog(@"frameInfo.absoluteString=[%@]",message.frameInfo.request.URL.absoluteString);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在JS中调用如下方法可以将信息传递到OC的 WKScriptMessageHandler 协议方法中

<a class="test-btn" onclick="window.webkit.messageHandlers.ocWkModth.postMessage({'page':'testVC','result':'success'})">测试</a>
  • 1

打印信息如下

2017-12-06 14:24:47.955640+0800 TestHybriod[2047:784478] body=[{    page = testVC;    result = success;}]2017-12-06 14:24:47.955845+0800 TestHybriod[2047:784478] name=[ocWkModth]
  • 1
  • 2
  • 3
  • 4
  • 5

源码-地址

四,其他粗暴的方法

在Native和js交互肯定是需要一个桥梁,在UIWebView中使用的是下面这个方法

webView.stringByEvaluatingJavaScript(from: "document.getElementById('index-kw').value = '1234';");
  • 1

在WKWebView中使用的是

webView.evaluateJavaScript("document.getElementById('index-kw').value = '1234abcd';") { (any, err) -> Void in    NSLog("any=" + (any as! String));} /*其实就是这个样子的,后面是swift的闭包*/  webView.evaluateJavaScript("document.getElementById('index-kw').value = '1234abcd';", completionHandler: nil);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

这两个方法是有返回值的,返回值就是html5页面中 element的value(可以片面的理解为UILable的text),虽然这个方法能执行JavaScript的代码,但只局限为可操作的一些元素和方法,这里给大家解释一下js一些简单的方法

/*通过这个id可以得到某个元素或者标签*/var lable_btn = document.getElementById('某个元素或者标签的id');/*可以set和get元素或者标签的value*/  lable_btn.value = 'value的值';/*通过这个ClassName可以得到某个元素或者标签  的数组*/var nodesInput = document.getElementsByClassName('input');nodesInput[0].value = 'test';
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在h5页面加载完成后,执行以下操作

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {webView.evaluateJavaScript("document.getElementById('index-kw').value = '1234';", completionHandler: nil);/*其实就是这个样子的,后面是swift的闭包*/ webView.evaluateJavaScript("document.getElementById('index-kw').value = '1234abcd';") { (any, err) -> Void in /*any 其实就是返回值*/        NSLog("any=" + (any as! String));  }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

*效果如下,其中 index-kw 是百度收索框的元素 id,给这个id的value,赋值。出现如下效果
这就是一个简单的交互*


但在实际开发中可能需要一些更高级的交互,这里没有使用网上的一些框架

/*这里可以监听和拦截 h5 页面的 alert*/func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void) {        if message == "商量好的信息" {            /*这里可以谈一个native的弹窗*/            //UIAlertController ....        }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

五,其他的交互机制–拦截机制
======H5页面跳转原生界面======
1,项目配置
在 info 里面 添加 URL Schemes

我在里添加的是 com.sir.pppig

然后在 appDegelate.m 中,监听

- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options{    NSLog(@"----]");    if (!url) {  return NO; }    // 可以在这里处理打开APP后的 业务逻辑    NSLog(@"new url= [%@]", url);    return YES;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

2,第一种 事件触发
然后在浏览器中输入 com.sir.pppig://, 就可以打开APP了,

点击 open ,打开APP,

3,第二种事件触发
在h5页面触发,

<div>            <h1>测试页面</h1>            <a id="openApp" href="com.sir.pppig://" style="border-radius: 0.05rem; display:block;margin:0 auto;padding:.1rem;color:#fff;background:#f07a0e;width:1.2rem;margin-bottom:.2rem;">打开APP</a >            <script>              document.getElementById('openApp').onclick = function (e) {                  /* location.href = 'com.sir.pppig://';                setTimeout(function() {                    location.href = '/toAppMobilePageTouch';                }, 250);                setTimeout(function() {                    location.reload();                }, 1000); */               /*  var ifr = document.createElement('iframe');                ifr.src = 'com.sir.pppig://';                ifr.style.display = 'none';                document.body.appendChild(ifr);                setTimeout(function(){                    document.body.removeChild(ifr);                }, 3000); */              }            </script>        </div>
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
ios js与oc原生WKWebView方法注入及交互传值
WKWebView与JS交互之实战技巧介绍
iOS开发 webView的学习及js交互
给产品经理讲技术丨网页与原生App如何交互
h5与App原生交互方案
Hybrid APP之Native和H5页面交互原理
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服