iOS开发-JS与原生OC互相调用之问题总结二

iOS js oc相互调用(JavaScriptCore)(二) 上节地址 http://blog.youkuaiyun.com/lwjok2007/article/details/47058101 接着上节我们讲到的iOS调用js 下来我们使用js调用iOS js调用iOS分两种情况 一,js里面直接调用方法 二,js里面通过对象调用方法 首先我们看第一种,直接调用方法。 其中用到了iOS的block 上代码 -(void)w 阅读详情

今天继续给同学们讲解JS和OC的互相调用,今天给大家还是讲解WKWebView中的一些使用,和注意点,废话不多说直接上代码:

 

#pragma mark - WKWebView中的MessageHandler?

WKWebView初始化时,有一个参数叫configuration,它是WKWebViewConfiguration类型的参数,而WKWebViewConfiguration有一个属性叫userContentController,它又是WKUserContentController类型的参数。WKUserContentController对象有一个方法

- addScriptMessageHandler:name:我把这个功能简称为MessageHandler。

- addScriptMessageHandler:name:有两个参数,第一个参数是userContentController的代理对象,第二个参数是JS里发送postMessage的对象(即你与前端JS定义好的方法名)。

 

 

#warning - 注意

所以要使用MessageHandler功能,就必须要实现WKScriptMessageHandler协议。

 

 

#pragma mark - <WebKit/WebKit.h>API中对JS的使用方法介绍?

我们在该API的描述里可以看到在JS中的使用方法:

window.webkit.messageHandlers.<name>.postMessage(<messageBody>) 

 

// 其中<name>,就是上面方法里的第二个参数'name';例:我们调用API的时候第二个参数填@"Share",那么在JS里就是: window.webkit.messageHandlers.Share.postMessage(<messageBody>)

 

// <messageBody>是一个键值对,键是body,值可以有多种类型的参数。

// 在'WKScriptMessageHandler'协议中,我们可以看到message是'WKScriptMessage'类型,有一个属性叫body

// 而注释里写明了body 的类型:Allowed types are NSNumber, NSString, NSDate, NSArray, NSDictionary, and NSNull.

 

 

#pragma mark - 那么问题来了,如何使用MessageHandler呢?

1> 创建WKWebViewConfiguration对象,配置各个API对应的MessageHandler,WKUserContentController对象可以添加多个scriptMessageHandler。示例代码:

 

/**

 *  创建一个WKWebViewConfiguration对象

 */

- (void)creatConfiguration

{

    WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];

    WKPreferences *preference = [[WKPreferences alloc] init]; // 对一个webView的属性设置

    preference.javaScriptCanOpenWindowsAutomatically = YES;

    configuration.preferences = preference;

}

 

#pragma mark - 一般在这里就设置整个view是webView

- (void)loadView

{

    [super loadView];

    

    self.view = self.webView;

}

 

#pragma mark - view即将出现的时候我们就可以监听

- (void)viewWillAppear:(BOOL)animated

{

    [super viewWillAppear:animated];

    

    // addScriptMessageHandler 很容易导致循环引用

    // 控制器 强引用了WKWebView,WKWebView copy(强引用了)configuration,configuration copy(强引用了)userContentController

    // userContentController 强引用了 self(控制器)

    [self.webView.configuration.userContentController addScriptMessageHandler:self name:@"ScanAction"];

    [self.webView.configuration.userContentController addScriptMessageHandler:self name:@"Location"];

    [self.webView.configuration.userContentController addScriptMessageHandler:self name:@"Share"];

    [self.webView.configuration.userContentController addScriptMessageHandler:self name:@"Color"];

    [self.webView.configuration.userContentController addScriptMessageHandler:self name:@"Pay"];

    [self.webView.configuration.userContentController addScriptMessageHandler:self name:@"Shake"];

    [self.webView.configuration.userContentController addScriptMessageHandler:self name:@"GoBack"];

    [self.webView.configuration.userContentController addScriptMessageHandler:self name:@"PlaySound"];

}

 

#warning - 需要注意的是addScriptMessageHandler很容易引起循环引用,导致控制器无法被释放,所以需要加入以下这段

- (void)viewWillDisappear:(BOOL)animated

{

    [super viewWillDisappear:animated];

    

    // 因此这里要记得移除handlers

    [self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"ScanAction"];

    [self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"Location"];

    [self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"Share"];

    [self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"Color"];

    [self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"Pay"];

    [self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"Shake"];

    [self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"GoBack"];

    [self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"PlaySound"];

}

 

#pragma mark - 创建WKWebView?

- (void)viewDidLoad {

    [super viewDidLoad];

    

    // 0.创建WKWebView

    [self setUpWebView];

    

    // 1.创建WKWebViewConfiguration对象

    [self setUpConfiguration];

}

 

/**

 *  创建webView

 */

- (void)setUpWebView

{

    self.webView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:nil];

    NSString *urlStr = [[NSBundle mainBundle] pathForResource:@"test.html" ofType:nil];

    NSURL *fileURL = [NSURL fileURLWithPath:urlStr];

    [self.webView loadFileURL:fileURL allowingReadAccessToURL:fileURL];

    

    self.webView.navigationDelegate = self;

    self.webView.UIDelegate = self;

    [self.view addSubview:self.webView];

}

 

/**

 *  创建一个WKWebViewConfiguration对象

 */

- (void)setUpConfiguration

{

    WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];

    WKPreferences *preference = [[WKPreferences alloc] init]; // 对一个webView的属性设置

    preference.javaScriptCanOpenWindowsAutomatically = YES;

    configuration.preferences = preference;

}

 

#pragma mark - 实现协议方法

#pragma mark - 我这里实现了两个协议<WKUIDelegate,WKScriptMessageHandler>,WKUIDelegate是因为我在JS中弹出了alert。WKScriptMessageHandler是因为我们要处理JS调用OC方法的请求。

#pragma mark - WKScriptMessageHandler

- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message

{

    //  message.body -- Allowed types are NSNumber, NSString, NSDate, NSArray,NSDictionary, and NSNull.

    if ([message.name isEqualToString:@"ScanAction"]) {

        NSLog(@"扫一扫");

    } else if ([message.name isEqualToString:@"Location"]) {

        [self test];

    } else if ([message.name isEqualToString:@"Share"]) {

        [self test];

    } else if ([message.name isEqualToString:@"Color"]) {

        [self test];

    } else if ([message.name isEqualToString:@"Pay"]) {

        [self test];

    } else if ([message.name isEqualToString:@"Shake"]) {

        [self test];

    } else if ([message.name isEqualToString:@"GoBack"]) {

        [self test];

    } else if ([message.name isEqualToString:@"PlaySound"]) {

        [self test];

    }

}

 

- (void)test

{

    

}

 

#pragma mark - WKScriptMessage有两个关键属性name和body。因为我们给每一个OC方法取了一个name,那么我们就可以根据name 来区分执行不同的方法。body中存着JS要给OC传的参数。关于参数body的解析,我就举一个body中放字典的例子.

/**

 *  @param tempDic tempDic来自message.body来自与JS传过来的参数

 */

- (void)shareWithParams:(NSDictionary *)tempDic

{

    if (![tempDic isKindOfClass:[NSDictionary class]]) return;

    

    // kvc取值

    NSString *title = [tempDic objectForKey:@"title"];

    NSString *content = [tempDic objectForKey:@"content"];

    NSString *url = [tempDic objectForKey:@"url"];

    

    // 在这里执行分享的操作

    

#pragma mark - OC调用JS

    // 将分享结果返回给js 即:OC调用JS

    NSString *jsStr = [NSString stringWithFormat:@"shareResult('%@','%@','%@')",title,content,url];

    [self.webView evaluateJavaScript:jsStr completionHandler:^(id _Nullable result, NSError * _Nullable error) {

        NSLog(@"%@----%@",result, error);

    }];

}

 

#pragma mark - 那么这里总结用MessageHandler的好处

/* 

 * 1> 在JS中写起来简单,不用再用创建URL的方式那么麻烦了。

 * 2> JS传递参数更方便。使用拦截URL的方式传递参数,只能把参数拼接在后面,如果遇到要传递的参数中有特殊字符,如&、=、?等,必须得转换,否则参数解析肯定会出错。

 * 例如传递的url是这样的:

 * http://www.baidu.com/share/openShare.htm?share_uuid=shdfxdfdsfsdf&name=1234567890

 * 使用拦截URL 的JS调用方式

 * loadURL("firstClick://shareClick?title=分享的标题&content=分享的内容&url=链接地址&imagePath=图片地址"); }

 * 将上面的url 放入链接地址这里后,根本无法区分share_uuid是其他参数,还是url里附带的参数。

 * 但是使用MessageHandler 就可以避免特殊字符引起的问题。

 */

 

  •  

 

 

 

 

 

 

 

 

iOS webView的高级用法之JS交互,js与oc的相互调用(JavaScriptCore) 重要的事情放前面 github地址:https://github.com/horisea/JSCallOCTest   欢迎star   前言:说起JS交互,很多童鞋会黯然色变,感觉很高深的样子。大部分小伙伴只知道一种,哪一种我也说说吧。    1.在webView中将要请求的时候,拦截URL,进行重定向,然而该场景实用有限,网上资料也很多下面说说另一种交互方式。 - (BOOL)webV... 阅读详情

相关推荐

iOS开发进阶(九):OC混合开发嵌套H5应用并互相通信_ios h5混合开发

/ 2: (a)WKWebView注入ScriptMessageHandler设置代理方法self, (用于调用H5方法)if ([[url scheme] isEqualToString:@“alert”]) {//拦截请求,弹出自定义对话框。}else if([[url scheme] isEqualToString:@“tel”]){//拦截拨打电话请求。//创建UserContentController(提供javaScript向webView发送消息的方法)//mj解析参数(此处可以忽略)

2401_86640470的博客 2080

iOS—— addScriptMessageHandler 引起WKWebView 循环引用问题

WKWebView 初始化时,有一个参数叫configuration,它是WKWebViewConfiguration类型的参数,而WKWebViewConfiguration有一个属性叫userContentController,它又是WKUserContentController类型的参数。WKUserContentController对象有一个方法- addScriptMessageHandler:name: - addScriptMessageHandler:name:有两个参数,第一个参数是us

cym_bj 2993

iOS WKWebView中MessageHandler内存泄漏问题的完美解决过程

主要给大家介绍了关于iOS WKWebView中MessageHandler内存泄漏问题的完美解决过程,文中通过示例代码介绍的非常详细,对各位iOS开发者们具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

[iOS]WKWebView之MesssageHandler

一、什么是MessageHandler   MessageHandler是WKWebView用来处理原生与JS交互的消息处理机制。也即是说:JS要想调用iOS原生的方法,可以采用MessageHandler。   二、怎么注入js的方法 WKWebView在创建的时候有一个属性:WKWebViewConfiguration,这个configuration有个WKUserContentCo...

sz_vcp2007的专栏 623

多模态变体—ALIGN:高效的图像-文本学习

ALIGN 论文介绍了该模型的关键技术。无人工标注数据:使用互联网数据进行训练,不依赖人工清洗的数据集。高效的对比学习策略:采用大规模图像-文本配对数据,通过对比学习优化嵌入空间。支持零样本(zero-shot)学习:可以在没有专门训练的情况下执行多种任务,如分类、检索等。可扩展性强:ALIGN 采用高效的 CNN 或 Transformer 作为编码器,适用于大规模计算。

Azperk的博客 1218

【Arduino 101】五分钟搞懂PID控制算法

【Arduino 101】五分钟搞懂PID控制算法物料清单尺寸接线 文章目录物料清单尺寸接线 物料清单 Arduino Uno x 1 超声波模块(HC-SR04)x 1 舵机(Tower Pro MG996R)x 1 舵机供电: 5V 稳压管(LM7805) x 1 , 滤波电容 (0.33uF, 0.1uF) x 2, 9V 电池 x 1 滑轨:泡沫板 支架:乐高 滚动物体:胶带(Up试过网球,但是测距模块的表现不理想) 尺寸 接线 ...

机器人工坊 1万+

iOS下JS与OC互相调用(三)--MessageHandler

使用WKWebView的时候,如果想要实现JS调用OC方法,除了拦截URL之外,还有一种简单的方式。那就是利用WKWebView的新特性MessageHandler来实现JS调用原生方法。 MessageHandler 是什么? WKWebView 初始化时,有一个参数叫configuration,它是WKWebViewConfiguration类型的参数,而WKWebViewConfigura...

zzg_1990的专栏 1128

Android 11系统定制:如何彻底隐藏状态栏电池图标(RK3568实测)

本文详细解析了在Android 11系统上如何通过多维度修改实现状态栏电池图标的彻底隐藏,特别针对RK3568平台提供了实战指南。从系统UI架构解析到核心配置文件修改,再到进阶技巧与疑难排查,帮助开发者深度定制Android系统,满足特定场景需求。

weixin_29250573的博客 373

iOS的JS和OC代码互相调用

1.JS调用OC代码 步骤1:以下是html页面,test1函数,并没有在页面中声明,而是在OC的UIWebView中绑定的             //test2(p)函数是准备 OC调用JS函数用的         function test2(p){             alert(p);         }         test1()" onc

VictorZhang 3245

Ragflow技术栈分析及二次开发指南

Ragflow是目前团队化部署大模型+RAG的优质方案,不过其仍不适合直接部署使用,本文将从实际使用的角度,对其进行二次开发

兴趣使然的创作者 1万+

汽车工程师必看:从CAN到Ethernet,6种车载通信协议全解析(附应用场景对比)

本文全面解析了从CAN到Ethernet的6种车载通信协议,包括CAN、LIN、MOST、FlexRay等,并对比了它们的应用场景和技术特点。文章详细介绍了各协议的演进历程、技术优势及在现代汽车中的混合网络架构设计,为汽车工程师提供了实用的协议选型指南和未来通信技术发展趋势。

weixin_28683689的博客 491

iOS WKWebview JS与OC互相调用,传递数据

前言:WKWebView是一个展示交互式web内容的视图,支持iOS8.0及macOS10.10以上的系统。提供了替换UIWebView的组件, WKWebView解决了UIWebView加载速度慢,占用内存多,优化困难等问题,可以说WKWebView是目前App内部加载网页的最佳选择。 目录 1.JS 与 OC 交互 2.OC 向 JS 传递值 1.JS 与 OC 交互 添加注...

俊而不逊的博客 9453

SIwave仿真手册——软件基础(一)

最近在学习SIWAVE,在这里将自己的笔记整理一下,做一个专题。希望对大家有帮助,这个会持续更新的。仅限于软件操作学习,不涉及信号完整性的讨论。

luohuo9844的博客 4万+

iOS下JS与原生OC互相调用

iOS开发免不了要与UIWebView打交道,然后就要涉及到JS与原生OC交互,今天总结一下JS与原生OC交互的两种方式。 JS调用原生OC篇 方式一 第一种方式是用JS发起一个假的URL请求,然后利用UIWebView的代理方法拦截这次请求,然后再做相应的处理。 我写了一个简单的HTML网页和一个btn点击事件用来与原生OC交互,HTML代码如下:

为你超神 3560

【车载以太网】【SOMEIP】Wireshark测试someip

一、 Wireshark SOMEIP plugin 1.1 插件安装 Wireshark插件目录:Help -> About Wireshark -> Folders/Pluginshttps://github.com/jamores/eth-ws-someip 解压后,将所有后缀是lua的文件拷贝到Wireshark安装目录plugins/2.4.10/下。 1.2时间戳调整为UTC显示格式 View -> Time Display Format -> Date and Tim.

专注汽车软件开发、AutoSAR、车载以太网、SOA、EE架构。 9725

AD9361功能介绍和使用

AD9361使用分数分频锁相环(PLL)来产生发射机和接收机本地振荡器(LO)频率和BB PLL。BB PLL 可用于数据转换、数字滤波器和 |/O 端口。PLL的参考时钟可以由外部振荡器或外部晶体(XO)和数字可编程片内可变电容提供,电容微调产生参考时钟频率,XO和微调电容的组合统称为DCXO。有多个天线输入的分集系统。接收链数据首先经过低噪声放大器(LNA),然后是同相(1)和正交(Q)放大器,混频器和频带整形滤波器,可将接收到的信号下变频为基带以进行数字化。时分双工(TDD)和频分双工(FDD)。。。

wangjie36的博客 1万+

iOS JS与OC交互

iOS JS与OC交互 1、UIWebView 与 JS 交互 UIWebView 在 iOS12 中已经被废弃,同时WKWebView在iOS8中已经出现。所以无特殊情况的话,我们一般应该也是用不到前者了! UIWebView 初始化: self.webView = [[UIWebView alloc] initWithFrame:self.view.bounds]; self.webView.delegate = self; [self.view addSubview:self.

kangpp的博客 2978

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

iOS开发进阶(九):OC混合开发嵌套H5应用并互相通信

APP开发过程中,当某些待集成三方SDK不得不使用原生技术栈集成实现时,抽离出公共功能部分并由H5实现是不错的解耦选择,为此便涉及到原生应用如何集成三方SDK,如何嵌套H5,并实现原生与H5通信。

IT全栈 华强工作室 2109

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

iOS下JS与OC互相调用

背景情况: app项目中有几个界面是需要经常变动的(不仅是内容还有UI布局等),比如活动宣传界面就是属于这一类。但是由于AppStore提交审核也是需要时间的,就算审核快,也不至于每次都为了这点事频繁审核吧。因此,这个界面就让Web组的来做HTML界面。 其实,如果只是安安静静的在app上展示下HTML,就很简单了。 JS与OC之间的交互,其实也就是两个方面,一种是点击HTML上的...

CCCCCC1990的博客 829

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

iOS WKWebView JS原生交互之JS调用OC(附demo)

WKWebView和UIWebView区别和其优缺点 大家都知道自从iOS8之后,推出了WKWebView,相较于UIWebView来说,性能和其稳定性也提高了不少,当然也有它的坑,大家自行选择,这里我用的是WKWebView WKWebView相比于UIWebView浏览器之间内核引擎的区别 JS调用OC 比如网页里有一个返回按钮,点击的时候需要pop到上一层。 OC @interf...

msbaby的博客 6675

JS OC JAVA互相调用

转自:https://www.cnblogs.com/billyrun/articles/8529503.html CocosCreator原生游戏js与oc/java互调 新项目需要在app游戏大厅中集成众多小游戏 仍然使用creator开发 然而若发布h5版本,用户首次加载时间相对较长 因此首批打算将游戏集成在app中,发布原生版本 这里总结一下ios原生版本开发过程中js与oc的...

ylwdi的专栏 1708

IOS WebView中JS和OC相互调用

现在有很多项目中都涉及到HTML5,在一个普通的APP里面嵌入HTML5网页,嵌入的这些网页在服务器把页面修改之后同样也能跟着修改,这样就能很方便的修改程序的展示内容。如果使用tabelView或者其他的控件展示内容的话,当展示的内容的样式需要发生改变的时候必须修改程序本身才能够达到修改的效果。所以,在APP里面HTML5的嵌入可以更加方便的维护程序的内容,但是由于现在受网速啊,手机性能等因素的影响

清风的博客 5313

iOS OC与JS交互实战

今天看见有人反对开源的,反对技术分享的,说这是方便了其他开发者,或者说最终是方便了资本家。但是我想说的是我也是从大家的技术分享中一点一点积累的技能,还是需要感谢先驱者的无私分享。 好了OC与JS交互是一个老的技术点,但是我发现网上大多数的文章都是互相抄,千篇一律,没有将里面的关系完全串联讲透。这个功能在开发的时候,避免不了是需要和Web前端沟通的,关键是前端可能也没有开发过这个功能,如果你也能知道一点点前端相关的知识点的话,工作效率会事半功倍。 这篇文章,我不会去装逼的讨论,到...

周为的博客 1672
上一篇: iOS开发-JS与原生OC互相调用之问题总结一
下一篇: iOS开发-屏幕适配之Autolayout&VFL&Masonry
ZZ_iOSDeveloper
博客等级 码龄11年 21粉丝 74原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值