swift 原生给h5发消息_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交互
首先使用到 框架中的 JSContext,JSExport对象。
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
- (void)testLog:(NSDictionary*)dict;
@end
@interface UIWeb_VC ()
@property UIWebView * webView;
@end
@implementation UIWeb_VC
//实现协议方法
- (void)testLog:(NSDictionary*)dict
{
NSLog(@"---testLog--");
NSLog(@"dict=[%@]",dict);
}
@end1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
最后在js中调用就方便了
UIWeb测试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,WebKit中 WKWebView使用的是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 协议方法中
测试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 *)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页面触发,
测试页面
打开APP
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); */
}
swift 原生给h5发消息_Swift-WKWebView与JavaScript的细节,H5页面跳转原生界面相关推荐
- swift 原生给h5发消息_Swift - 使用HTML5进行iOS开发(将HTML5打包成iOS应用)
下面简单介绍下如何把HTML5编写的页面编译成iOS应用,以及如何让页面与Swift代码进行交互.(本文代码已升级至Swift3) 1,使用UIWebView还是WKWebView来加载html页面 ...
- 火狐浏览器如何禁止网站发消息 火狐浏览器禁止网站发消息的方法
火狐浏览器是一款非常安全的浏览器,有很多的小伙伴都在使用它,很多朋友在使用火狐浏览器时都遇到过网站请求发送消息通知权限的情况,那么应该如何解决这个问题呢?下面就和小编一起来看看有什么好的方法吧. 火狐 ...
- php如何制定跳转到app原生页面,js实现界面向原生界面发消息并跳转功能
本文实例为大家分享了js界面向原生界面发消息并跳转的具体代码,供大家参考,具体内容如下 步骤一 在idea中,打开rn项目下的./Android/app,这个过程需要一点儿时间,可能还需要下载grad ...
- 微信小程序与webview H5交互(内嵌H5跳转原生页面)
在开发中,使用web-view组件内嵌H5页面是非常常见的,但很多人不知道webview内嵌H5如何与原生小程序 交互.下面介绍下实现微信小程序与webview H5交互的方法. web-view功能 ...
- springboot+websocket+token验证+jedis支持集群部署发消息
目录 websocket主要代码 pom.xml MyWebSocketHandler WSInterceptor WebSocketConfig Redis订阅广播实现Session共享 pom.x ...
- 1.低权限的程序向高权限的程序发消息 2.慎用setcurrentdirectory
1.低权限的程序向高权限的程序发消息 2.慎用setcurrentdirectory 转载于:https://www.cnblogs.com/chunyou128/p/3921903.html
- 原生 Java 客户端进行消息通信
原生 Java 客户端进行消息通信 Direct 交换器 DirectProducer:direct类型交换器的生产者 NormalConsumer:普通的消费者 MulitBindConsumer: ...
- mfc 按钮点第一下没触发消息 第二下才触发消息_34 详细干货 | 给回避型伴侣发消息,他们不回复,该怎么办?...
"我想我大概是一个不值得被爱的小孩吧"这是所有回避型依恋者最真实的内心写照.他们在感情中(至少是前期阶段),通常是很难信任他人,因为过去的经验告诉他们:别人是不可能给我情感满足的, ...
- Win7命令行局域网发消息图解
一 操作实例 在本机实验: Win7下net send命令已经取消: 改用msg对本机发送:收到后弹出消息框: 对55机器发送,出现1722错误:可能55没有开机: Win7下已经无messenger ...
最新文章
- Java中 this关键字详解
- mysql自然连接和等值连接_mysql sql99语法 内连接等值连接
- 数据绑定控件之Repeater
- C++中逗号操作符重载的分析
- flutter中本地存储shared_preferences的使用
- 35岁之后程序员的认可度不是很高
- windows 加域
- Log4j的快速入门
- 面试了上百位性能测试后,我发现了一个令人不安的事实
- ❤️《大前端—了解与使用ES6》
- python卸载_如何为Python程序制作Windows安装包?
- Java基础知识强化之网络编程笔记22:Android网络通信之 Android常用OAuth登录(获取个人信息)...
- 【资源分享】Dll Injector(DLL注入器)
- python函数输入参数数量_如何实现Python函数的参数不限个数?
- 通过PS把素色的旗袍换成青花瓷样式的旗袍
- 事务隔离级别与事务传播行为简介
- 一款利用PIN管设计的可调衰减器
- Springboot+WebSocket实现一个聊天室
- 大连理工计算机科学与技术,学院概况-大连理工大学计算机科学与技术学院
- 常见数据结构-栈-队列-数组-链表-哈希表
热门文章
- [python] LDA处理文档主题分布代码入门笔记
- 2015年第六届蓝桥杯 - 省赛 - C/C++大学B组 - C. 三羊献端
- PIL Image resize 调整大小谜之操作
- pip通过阿里源安装
- 2015年第六届蓝桥杯 - 省赛 - C/C++大学A组 - A. 方程整数解
- 新手入门机器学习十大算法
- 【物联网】 ESP8266 Ubuntu开发环境的搭建
- 【Linux网络编程】多播、组播
- linux+android4.2键值关系,Android4.0 添加一个新的Android 键值
- C语言ODBC方式连接DM数据库