热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

MHGJavascriptBridge简介

用途在iOS开发中,我们经常会碰到这样的需求:在UIWebView中的一个链接,点了之后不是进下一个网页,而是进下一个UIViewController,或者让ObjC代码做点事情。

用途

在iOS开发中,我们经常会碰到这样的需求:在UIWebView中的一个链接,点了之后不是进下一个网页,而是进下一个UIViewController,或者让ObjC代码做点事情。这在资讯类的应用中很常见,比如网易新闻、腾讯新闻,以及我们公司的东方财富通中的资讯。

而在旧的iOS版本中,系统不提供在Javascript直接调用ObjC的方法。只能通过变换location等发起网络请求的方式,使得UIWebViewDelegate中的- (BOOL)webView:shouldStartLoadWithRequest:navigationType:感知到,进而做ObjC的处理。

然而这样做比较不优雅,所有的事情都围绕在URL请求上面,而不是方法调用上面,看上去不优雅。MHGJavascriptBridge的用意便是将URL请求等等封装起来,让Javascript和ObjC代码注重于方法调用本身上来。

Github地址:https://github.com/hikui/MHGJavascriptBridge

使用方法

MHGJavascriptBridge由3个文件组成,MHGJavascriptBridge.h, MHGJavascriptBridge.m, MHGJavascriptBridge.js。将这三个文件加入Xcode工程中。注意,MHGJavascriptBridge.js必须加入到资源文件中(在”Building phases” -> “Copy bundle resources”中出现),Xcode默认会将.js文件加入到Compile Sources里面去,这是错误的。

Objective C设置

首先,我们需要初始化一个bridge,这通常是在一个UIViewController中进行的。这里假设在UIViewController中对bridge进行初始化。在初始化中,需要设定bridge的webView属性:

@interface MHGWebViewController ()
@property (nonatomic, strong) MHGJavascriptBridge *bridge;
@property (nonatomic, strong) UIWebView *webView;
@end
...
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
_bridge = [[MHGJavascriptBridge alloc]init];
_bridge.webView = self.webView;
}
return self;
}

在MHGJavascriptBridge中,所有能被Javascript调用的Objective C方法将以block的形式呈现。首先我们需要定义一些blocks,然后对每一个block起名。

- (void)viewDidLoad
{
[super viewDidLoad];
[self.bridge setBlockName:@"button1OnClick" block:^(NSDictionary *dict) {
// do stuff
NSLog(@"button1 on click with params:%@", dict);
}];
[self.bridge setBlockName:@"beginSomeTasks" block:^(NSDictionary *dict) {
// do stuff
NSLog(@"begin some tasks with params:%@", dict);
}];
...
}

MHGJavascriptBridge的原理是构造特定的URL,并且用UIWebViewDelegate中的- (BOOL)webView:shouldStartLoadWithRequest:navigationType:拦截这个URL。所以在这个delegate方法中,我们需要加入拦截语句:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
BOOL intercepted = [self.bridge interceptRequest:request]; //必须有
// Do other things ...
return YES;
}

其中,interceptRequest:方法会返回一个BOOL,如果拦截成功,则返回YES

这样,Objective C部分就设置完成了。其中需要注意的是,block被调用时,会传入一个dict,这是Javascript部分代码调Objective C代码时所传的参数。

Javascript设置

Javascript部分设置比较简单,最基本的设置是要保证UIWebView中的HTML引入了MHGJavascriptBridge.js


Javascript调用Objective C代码

一旦设置完成之后,Javascript和Objective C就能互相调用了。代码如下:

var button1ClickEventHandler = function (){
// Do stuff ...
MHGJavascriptBridge.callNativeBlock('button1OnClick',{'url':imageURL});
};

这时,点击button1时,就能触发Objective C的代码了。MHGJavascriptBridge.callNativeBlock有两个参数,第一个参数是在Objective C中注册的block名字,第二个参数是传给block里面的dict的额外信息。其中第二个参数必须是一个字典(或者说是一个Javascript Object),或者什么都不传。

Objective C调用Javascript代码

方法和上述类似:

...
[self.bridge callJavascriptFunction:@"setImageWithURL" withParams:@[fileURL.absoluteString]];
...

其中第一个参数是Javascript函数名。如果你在HTML中定义了function xxx(){}或者var xxx = function(){}的话,就能被调用。第二个参数是一个数组,传的是Javascript函数要用的参数列。

局限性

  • Javascript调用Objective C时,所有的调用都是异步的,暂时无法实现同步调用。
  • Javascript调用Objective C时,所传参数受URL长度限制而限制。

推荐阅读
  • 为了在Hadoop 2.7.2中实现对Snappy压缩和解压功能的原生支持,本文详细介绍了如何重新编译Hadoop源代码,并优化其Native编译过程。通过这一优化,可以显著提升数据处理的效率和性能。此外,还探讨了编译过程中可能遇到的问题及其解决方案,为用户提供了一套完整的操作指南。 ... [详细]
  • 优化后的标题:深入探讨网关安全:将微服务升级为OAuth2资源服务器的最佳实践
    本文深入探讨了如何将微服务升级为OAuth2资源服务器,以订单服务为例,详细介绍了在POM文件中添加 `spring-cloud-starter-oauth2` 依赖,并配置Spring Security以实现对微服务的保护。通过这一过程,不仅增强了系统的安全性,还提高了资源访问的可控性和灵活性。文章还讨论了最佳实践,包括如何配置OAuth2客户端和资源服务器,以及如何处理常见的安全问题和错误。 ... [详细]
  • Web开发框架概览:Java与JavaScript技术及框架综述
    Web开发涉及服务器端和客户端的协同工作。在服务器端,Java是一种优秀的编程语言,适用于构建各种功能模块,如通过Servlet实现特定服务。客户端则主要依赖HTML进行内容展示,同时借助JavaScript增强交互性和动态效果。此外,现代Web开发还广泛使用各种框架和库,如Spring Boot、React和Vue.js,以提高开发效率和应用性能。 ... [详细]
  • 利用爬虫技术抓取数据,结合Fiddler与Postman在Chrome中的应用优化提交流程
    本文探讨了如何利用爬虫技术抓取目标网站的数据,并结合Fiddler和Postman工具在Chrome浏览器中的应用,优化数据提交流程。通过详细的抓包分析和模拟提交,有效提升了数据抓取的效率和准确性。此外,文章还介绍了如何使用这些工具进行调试和优化,为开发者提供了实用的操作指南。 ... [详细]
  • 该问题可能由守护进程配置不当引起,例如未识别的JVM选项或内存分配不足。建议检查并调整JVM参数,确保为对象堆预留足够的内存空间(至少1572864KB)。此外,还可以优化应用程序的内存使用,减少不必要的内存消耗。 ... [详细]
  • 在本文中,我们将为 HelloWorld 项目添加视图组件,以确保控制器返回的视图路径能够正确映射到指定页面。这一步骤将为后续的测试和开发奠定基础。首先,我们将介绍如何配置视图解析器,以便 SpringMVC 能够识别并渲染相应的视图文件。 ... [详细]
  • 如何在页面底部添加倾斜样式效果? ... [详细]
  • 在近期的项目开发过程中,ORM层采用了MyBatis,并且需要连接多个数据库,这带来了多数据源配置的挑战。为了解决这一问题,我们可以通过巧妙运用注解来实现优雅的数据源切换,确保系统的灵活性和可维护性。这种方法不仅简化了配置,还提高了代码的可读性和扩展性。 ... [详细]
  • 我正在使用 Ruby on Rails 构建个人网站。总体而言,RoR 是一个非常出色的工具,它提供了丰富的功能和灵活性,使得创建自定义页面变得既高效又便捷。通过利用其强大的框架和模块化设计,我可以轻松实现复杂的功能,同时保持代码的整洁和可维护性。此外,Rails 的社区支持也非常强大,为开发过程中遇到的问题提供了丰富的资源和解决方案。 ... [详细]
  • 从零起步:使用IntelliJ IDEA搭建Spring Boot应用的详细指南
    从零起步:使用IntelliJ IDEA搭建Spring Boot应用的详细指南 ... [详细]
  • 分享一下最近写的ReactNative的SSHSFTP组件,iOS端封装了NMSSH,Android端封装了JSch。支持SSH执行命令、实时Shell ... [详细]
  • 通过优化动态网络Cookies的全网互通机制,实现了用户在任意子站点的登录和注销操作均能同步至整个网络。具体实现涉及对三个关键文件的修改:首先,在`incDv_ClsMain.asp`中定位并调整`Response.Cookies`的相关设置;其次,更新`global.asa`以确保会话状态的一致性;最后,修改`login.asp`以支持跨域认证。这一改进不仅提升了用户体验,还增强了系统的安全性和可靠性。 ... [详细]
  • 为了确保iOS应用能够安全地访问网站数据,本文介绍了如何在Nginx服务器上轻松配置CertBot以实现SSL证书的自动化管理。通过这一过程,可以确保应用始终使用HTTPS协议,从而提升数据传输的安全性和可靠性。文章详细阐述了配置步骤和常见问题的解决方法,帮助读者快速上手并成功部署SSL证书。 ... [详细]
  • 本文深入解析了WCF Binding模型中的绑定元素,详细介绍了信道、信道管理器、信道监听器和信道工厂的概念与作用。从对象创建的角度来看,信道管理器负责信道的生成。具体而言,客户端的信道通过信道工厂进行实例化,而服务端则通过信道监听器来接收请求。文章还探讨了这些组件之间的交互机制及其在WCF通信中的重要性。 ... [详细]
  • 使用 ListView 浏览安卓系统中的回收站文件 ... [详细]
author-avatar
sawrf12454_191
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有