iOS与JS交互实战篇(ObjC版)

前言

ObjectiveC与Js交互是常见的需求,可对于新手或者所谓的高手而言,其实并不是那么简单明了。这里只介绍iOS7.0后出来的JavaScriptCore framework。
关于JavaScriptCore

本教程中所涉及到的几种类型:

JSContext, JSContext是代表JS的执行环境,通过-evaluateScript:方法就可以执行一JS代码
JSValue, JSValue封装了JS与ObjC中的对应的类型,以及调用JS的API等
JSExport, JSExport是一个协议,遵守此协议,就可以定义我们自己的协议,在协议中声明的API都会在JS中暴露出来,才能调用

ObjC与JS交互方式

通过JSContext,我们有两种调用JS代码的方法:

1、直接调用JS代码
2、在ObjC中通过JSContext注入模型,然后调用模型的方法

直接调用JS代码

// 一个JSContext对象,就类似于Js中的window,
// 只需要创建一次即可。
self.jsContext = [[JSContext alloc] init];

// jscontext可以直接执行JS代码。
[self.jsContext evaluateScript:@"var num = 10"];
[self.jsContext evaluateScript:@"var squareFunc = function(value) { return value * 2 }"];
// 计算正方形的面积
JSValue *square = [self.jsContext evaluateScript:@"squareFunc(num)"];

// 也可以通过下标的方式获取到方法
JSValue *squareFunc = self.jsContext[@"squareFunc"];
JSValue *value = [squareFunc callWithArguments:@[@"20"]];
NSLog(@"%@", square.toNumber);
NSLog(@"%@", value.toNumber);

这种方式是没有注入模型到JS中的。这种方式使用起来不太合适,通常在JS中有很多全局的函数,为了防止名字重名,使用模型的方式是最好不过了。通过我们协商好的模型名称,在JS中直接通过模型来调用我们在ObjC中所定义的模型所公开的API。
通过注入模型的方式交互

首先,我们需要先定义一个协议,而且这个协议必须要遵守JSExport协议。

@protocol JavaScriptObjectiveCDelegate

// JS调用此方法来调用OC的系统相册方法
- (void)callSystemCamera;
// 在JS中调用时,函数名应该为showAlertMsg(arg1, arg2)
// 这里是只两个参数的。
- (void)showAlert:(NSString *)title msg:(NSString *)msg;
// 通过JSON传过来
- (void)callWithDict:(NSDictionary *)params;
// JS调用Oc,然后在OC中通过调用JS方法来传值给JS。
- (void)jsCallObjcAndObjcCallJsWithDict:(NSDictionary *)params;

@end

接下来,我们还需要定义一个模型:

// 此模型用于注入JS的模型,这样就可以通过模型来调用方法。
@interface HYBJsObjCModel : NSObject

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

@end

实现这个模型:

@implementation HYBJsObjCModel

- (void)callWithDict:(NSDictionary *)params {
NSLog(@"Js调用了OC的方法,参数为:%@", params);
}

// Js调用了callSystemCamera
- (void)callSystemCamera {
NSLog(@"JS调用了OC的方法,调起系统相册");

// JS调用后OC后,又通过OC调用JS,但是这个是没有传参数的
JSValue *jsFunc = self.jsContext[@"jsFunc"];
[jsFunc callWithArguments:nil];
}

- (void)jsCallObjcAndObjcCallJsWithDict:(NSDictionary *)params {
NSLog(@"jsCallObjcAndObjcCallJsWithDict was called, params is %@", params);

// 调用JS的方法
JSValue *jsParamFunc = self.jsContext[@"jsParamFunc"];
[jsParamFunc callWithArguments:@[@{@"age": @10, @"name": @"lili", @"height": @158}]];
}

- (void)showAlert:(NSString *)title msg:(NSString *)msg {
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertView *a = [[UIAlertView alloc] initWithTitle:title message:msg delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
[a show];
});
}

@end

接下来,我们在controller中在webview加载完成的代理中,给JS注入模型。

#pragma mark - UIWebViewDelegate
- (void)webViewDidFinishLoad:(UIWebView *)webView {
self.jsContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
// 通过模型调用方法,这种方式更好些。
HYBJsObjCModel *model = [[HYBJsObjCModel alloc] init];
self.jsContext[@"OCModel"] = model;
model.jsContext = self.jsContext;
model.webView = self.webView;

self.jsContext.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {
context.exception = exceptionValue;
NSLog(@"异常信息:%@", exceptionValue);
};
}

我们是通过webView的valueForKeyPath获取的,其路径为documentView.webView.mainFrame.javaScriptContext。
这样就可以获取到JS的context,然后为这个context注入我们的模型对象。

我们先写两个JS方法:

var jsFunc = function() {
alert(‘Objective-C call js to show alert‘);
}

var jsParamFunc = function(argument) {
document.getElementById(‘jsParamFuncSpan‘).innerHTML
= argument[‘name‘];
}

这里我们定义了两个JS方法,一个是jsFunc,不带参数。
另一个是jsParamFunc,带一个参数。

接下来,我们在html中的body中添加以下代码:

Test how to use objective-c call js

现在就可以测试代码了。

当我们点击第一个按钮:Call ObjC system camera时,
通过OCModel.callSystemCamera(),就可以在HTML中通过JS调用OC的方法。
在OC代码中,我们的callSystemCamera方法体中,添加了以下两行代码,就是获取HTML中所定义的JS就去jsFunc,然后调用它。

JSValue *jsFunc = self.jsContext[@"jsFunc"];
[jsFunc callWithArguments:nil];

这样就可以在JS调用OC方法时,也让OC反馈给JS。

看看下面传字典参数:

- (void)jsCallObjcAndObjcCallJsWithDict:(NSDictionary *)params {
NSLog(@"jsCallObjcAndObjcCallJsWithDict was called, params is %@", params);

// 调用JS的方法
JSValue *jsParamFunc = self.jsContext[@"jsParamFunc"];
[jsParamFunc callWithArguments:@[@{@"age": @10, @"name": @"lili", @"height": @158}]];
}

获取我们在HTML中定义的jsParamFunc方法,然后调用它并传了一个字典作为参数。

时间: 2024-10-29 20:19:07

iOS与JS交互实战篇(ObjC版)的相关文章

IOS Webview JS交互之事件拦截获取

最近项目中用到了webvVew,webView加载的网页中有两个按钮,要在app里面响应这两个按钮的点击事件,并接受JS传过来的参数. ios7 的时候,出来了一个新的类库叫JavaScriptCore.framework - (void)setupJsContent { //获取当前JS环境 _content = [_webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]; // 打印异

WKWebView与JS交互实战技巧之API介绍

前言 前一章我给大家介绍了iOS与HTML5的交互,用的是UIWebView,今天给大家介绍另外一种基于 iOS 8 新推出的 WKWebView 组件,构建出自己的混合开发框架. WKWebView 简介 WKWebView 是苹果在 iOS 8 中引入的新组件,目的是给出一个新的高性能的 Web View 解决方案,摆脱过去 UIWebView 的老旧笨重特别是内存占用量巨大的问题. 苹果将 UIWebViewDelegate 与 UIWebView 重构成了 14 个类和 3 个协议,引入

iOS与JS交互

① iOS -> JS 原理:通过WebView的方法直接调用JS代码 [WebView stringByEvaluatingJavaScriptFromString:@"A"]; // 这里的 A 就是WebView中的html所对应的JS代码 eg. 1)这里一个html所包含的js文件内的一个public方法 2)这是一个.m(iOS)文件内的一个WebView的调用1)中js方法的写法 3)那么在js的对应方法中,就会得到来自iOS的参数 ② JS -> iOS 原

iOS开发——使用技术OC篇&剪切版的实现

剪切版的实现 在iOS中,可以使用剪贴板实现应用程序之中以及应用程序之间实现数据的共享.比如你可以从iPhone QQ复制一个url,然后粘贴到safari浏览器中查看这个链接的内容. 一.在iOS中下面三个控件,自身就有复制-粘贴的功能: 1.UITextView 2.UITextField 3.UIWebView 二.UIKit framework提供了几个类和协议方便我们在自己的应用程序中实现剪贴板的功能. 1.UIPasteboard:我们可以向其中写入数据,也可以读取数据 2.UIMe

ios与js交互获取webview元素和赋值

使用webview的stringByEvaluatingJavaScriptFromString的方法交互,直接提供实例. 下载:http://download.csdn.net/detail/heyuan110/4420050 附上document.location.body 属性方法 JS 对象 document:属性 document.title //设置文档标题等价于HTML的<title>标签 document.bgColor //设置页面背景色 document.fgColor /

Node.js Stream - 实战篇

邹斌 ·2016-07-22 11:04 背景 前面两篇(基础篇和进阶篇)主要介绍流的基本用法和原理,本篇从应用的角度,介绍如何使用管道进行程序设计,主要内容包括: 管道的概念 Browserify的管道设计 Gulp的管道设计 两种管道设计模式比较 实例 Pipeline 所谓“管道”,指的是通过a.pipe(b)的形式连接起来的多个Stream对象的组合. 假如现在有两个Transform:bold和red,分别可将文本流中某些关键字加粗和飘红.可以按下面的方式对文本同时加粗和飘红: //

iOS 与 js交互的其一方法 WebViewJavascriptBridge的使用

#import <WebViewJavascriptBridge.h> /// @interface ZWBridgeViewController ()<WKNavigationDelegate, WKUIDelegate, UIGestureRecognizerDelegate> @property (nonatomic, strong) ZWCommonNavBar *navBar; @property (nonatomic, strong) WKWebView *webVie

IOS与js的简单交互swift3版

在开发过程中,我们可能遇到ios代码与js交互的情况,本人第一次使用遇到了很多坑,这里纪录一下,方便自己,也方便需要的人. p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Menlo; color: #e7e8ec } p.p2 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Menlo; color: #e7e8ec; min-height: 14.0px } span.s1 { colo

iOS开发——网络开发OC篇&amp;OC与JS交互简单案例

OC与JS交互简单案例 网页开发中三个重要的知识,这里就不详细介绍了! Html:页面代码 Css:样式 javascript:响应 先来看一段html的简单代码,里面涉及了上面的三个部分(很简单) 1 <html> 2 <!--描述网页信息--> 3 <head> 4 <meta charset="UTF-8"/> 5 <title>hello world</title> 6 <script> 7 f