native与web交互的那些事儿

项目中经常会出现需要native和web交互的地方,我推荐两种方法。一种是通过JavaScriptCore,一种是通过拦截网络请求的方式

第一种方式

1、先介绍几个名词:

  • JSContext:给JavaScript提供运行的上下文环境
  • JSValue:JavaScript和Objective-C数据和方法的桥梁
  • JSExport:这是一个协议,如果采用协议的方法交互,自己定义的协议必须遵守此协议

2、先来看个html

<html>
    <head>
        <meta charset="UTF-8">
        <script>
            var callShare = function()
            {
                var shareInfo = JSON.stringify({"title": "标题", "desc": "内容", "shareUrl": "http://www.baidu.com","shareIco":"https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/logo_white_fe6da1ec.png"});
                HH.shareToObjc(shareInfo);
            }
            var picCallback = function(photos)
            {
                alert(photos);
            }

            var shareCallback = function()
            {
                alert(‘success‘);
            }
        </script>
</head>
<body>
    <h1>Objective-C和JavaScript交互的那些事</h1>
        <div>
            <input type="button" value="调用相册" onclick="HH.callCamera()">
        </div>
        <div>
            <input type="button" value="分享字符串" onclick="callShare()">
        </div>
</body>
</html>

  从Html中的JavaScript函数 HH.shareToObjc(shareInfo) 函数指向了native方法

3、看个native文件

#import "ViewController.h"
#import <JavaScriptCore/JavaScriptCore.h>

@protocol JSObjcDelegate <JSExport>
/**
 *  调用相册
 */
- (void)callCamera;
/**
 *  分享字符串
 *
 *  @param shareString 字符串
 */
- (void)shareToObjc:(NSString *)shareString;

@end

@interface ViewController ()<UIWebViewDelegate,JSObjcDelegate>

@property (nonatomic,strong)  JSContext *jsContext;
@property (weak, nonatomic) IBOutlet UIWebView *webView;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    NSURL* url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"test" ofType:@"html"]];
    [self.webView loadRequest:[NSURLRequest requestWithURL:url]];
}

#pragma mark UIWebViewDelegate

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    self.jsContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    self.jsContext[@"HH"] = self;
    self.jsContext.exceptionHandler = ^(JSContext *context, JSValue *exception)
    {
        NSLog(@"异常信息:%@",exception);
    };
}

#pragma mark JSObjcDelegate

- (void)shareToObjc:(NSString*)shareString
{
    NSLog(@"%@",shareString);
    [self.jsContext[@"shareCallback"]callWithArguments:nil];
}

- (void)callCamera
{
    JSValue* picCallback = self.jsContext[@"picCallback"];
    [picCallback callWithArguments:@[@"图片"]];
}
@end

  自定义JSObjcDelegate协议,而且此协议必须遵守JSExport这个协议,自定义协议中的方法就是暴露给web页面的方法。在webView加载完毕的  时候获取JavaScript运行的上下文环境,然后再注入桥梁对象名为HH,承载的对象为self即为此控制器,控制器遵守此自定义协议实现协议中对应的方法。在JavaStript调用完本地应用的方法做完相对应的事情之后,又回调了JavaStript中对应的方法,从而实现了web页面和本地应用之间的通讯。

第二种方式

1、在JavaScript代码中使用 window.location.href = "HH://";  //自定义协议

2、在Native中使用以下代码来拦截网络请求

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    NSString *url = request.URL.absoluteString;
    if ([url rangeOfString:@"HH://"].location != NSNotFound) {
        NSLog(@"callCamera");
        return NO;
    }
    return YES;
}

拦截到网络请求之后对不通的自定义协议进行分发处理,但是这样就无法通过回调的方式调用JavaScript中的回调函数了,可以通过调用stringByEvaluatingJavaScriptFromString函数将数据传递给JavaScript达到相同的效果

时间: 2024-12-09 20:49:50

native与web交互的那些事儿的相关文章

客户端技术的一点思考(数据存储用SQLite, XMPP通讯用Gloox, Web交互用LibCurl, 数据打包用Protocol Buffer, socket通讯用boost asio)

今天看到CSDN上这么一篇< 彻底放弃没落的MFC,对新人的忠告!>, 作为一个一直在Windows上搞客户端开发的C++程序员,几年前也有过类似的隐忧(参见 落伍的感觉), 现在却有一些不同的想法. 首先,个人职业发展是否成功, 技术只是其中一小块,尤其是在大公司, 更多的是依靠所谓的软实力.作为一个对技术有追求的工匠,我们下面重点说技术相关的. 现在回头看计算机行业的发展,我们看到不同的发展阶段: 1. PC时代,这个时代离我们并不遥远, 也有是2000年前后, 该时代最鲜明的特征是Win

Hybrid APP基础篇(二)-&gt;Native、Hybrid、React Native、Web App方案的分析比较

说明 Native.Hybrid.React.Web App方案的分析比较 目录 前言 参考来源 前置技术要求 楔子 几种APP开发模式 概述 Native App Web App Hybrid App React Native App 分析 各大开发模式直观对比 如何选择开发模式 另类的app方案 微网页 微信小程序 其它 前言 参考来源 前人栽树,后台乘凉,本文参考了以下来源 对当前主流hybrid app.web app与native app工具的初步比较与分析 H5.React Nati

Native 还是 Web ? 这,不是问题

前 言 移动App是对URL和搜索引擎的革命,当今移动App开发貌似出现两大阵营,Native 和 Web,各自都认为自己代表未来的趋势,Native操作流畅.迅速,Web开发周期相对较短,还能轻松跨平台,但是,在项目的实际应用中到底如何?接下来,我们根据开发人员的讨论,做一个对比分析就知道答案了~ 对比分析   Native App  Web App 优势 1.用户体验稳定.流畅 2.优质界面.优雅交互 3.容易被记住,留存率高 4.用户黏度高 5.支持离线功能 6.可直接操作本地资源 7.传

Native App,Web App 还是 Hybrid app

一.Native App,Web App 还是 Hybrid app nativeapp是一个原生程序,一般运行在机器操作系统上,有很强的交互,一般静态资源都是在本地的.浏览使用方便,体验度高.在实现上要么使用Objecttive-c和cocoaTouch Framework撰写IOS程序,要么选择java+Android Framework撰写android应用程序. hybridapp是一个半原生程序,伪造了一个浏览器的apk/ipa原生程序,把地址写死了,然后里面运行了一个webapp.里

Native、Web App、Hybrid、React Native(简称RN)、Weex 间的异同点。

App常用开发模式简介 此处App为应用application,并非我们通常讲的手机App. 常用的几种APP开发模式-脑图 Native App 传统的原生App开发模式,有iOS和aOS两大系统,需要各自语言开发各自App. 优点:性能和体验都是最好的. 缺点:开发和发布成本高. 举个栗子:网易管家App (https://id.163.com/gj/) 应用技术:Swift,OC,Java. WebApp 移动端的网站,常被称为H5应用,说白了就是特定运行在移动端浏览器上的网站应用.一般泛

纠结的CLI C++与Native C++的交互

最近在写点东西,涉及到了CLR C++与Native C++的互相调用的问题,结果...........纠结啊. 交互原型 交互原型是这样的: void* avio_alloc_context( unsigned char *buffer, int buffer_size, int write_flag, void *opaque, int (*read_packet)(void *opaque, uint8_t *buf, int buf_size), int (*write_packet)(

Android -- 与WEB交互在同一个会话Session中通信

Session与Cookie Cookie和Session都为了用来保存状态信息,都是保存客户端状态的机制,它们都是为了解决HTTP无状态的问题而所做的努力. Session可以用Cookie来实现,也可以用URL回写的机制来实现. Cookie和Session有以下明显的不同点: 1)Cookie将状态保存在客户端,Session将状态保存在服务器端: 2)Cookies是服务器在本地机器上存储的小段文本并随每一个请求发送至同一个服务器.网络服务器用HTTP头向客户端发送cookies,在客户

Web Service 那点事儿(4)—— 使用 CXF 开发 REST 服务

现在您已经学会了如何使用 CXF 开发基于 SOAP 的 Web 服务,也领略了 Spring + CXF 这个强大的组合,如果您错过了这精彩的一幕,请回头看看这篇吧: Web Service 那点事儿(2) —— 使用 CXF 开发 SOAP 服务 今天我们将视角集中在 REST 上,它是继 SOAP 以后,另一种广泛使用的 Web 服务.与 SOAP 不同,REST 并没有 WSDL 的概念,也没有叫做“信封”的东西,因为 REST 主张用一种简单粗暴的方式来表达数据,传递的数据格式可以是

10 个基于 jQuery 的 Web 交互插件推荐

英文原文:10 jQuery for Web Interaction Plugins "用户交互"在现代的 Web 设计中占据了很大比例,这是互联网产品不可或缺的关键,对 Web 设计师也提出了更高的要求. 本文整理了 10 款基于 jQuery 的 Web 交互插件,可以帮助你提高工作效率,或带给你一些设计灵感. 1.   Redactor:奇妙的所见即所得编辑器 该工具有一个非常好的 API,允许你根据需要进行定制. 源码 / 演示 2.   elFinder:基于 web 的文件