JavaScriptCore 运用

媒介

动态化是挪动开辟手艺中的主要的一部份 ,当前广泛的动态化计划 , 如 React Native 、Weex 、Hybrid部份解决计划及之前盛行的热修复框架 JSPatch ,背地都用到了 JavaScriptCore 框架 ,由它建立起 OC 跟 JS 言语沟通的桥梁 。

JavaScriptCore 引见

JavaScriptCore 是 Safari 浏览器 JavaScript 引擎 ,它用来诠释和实行 JavaScript 代码 。

JavaScriptCore 框架是一个苹果在 iOS7 引入的框架 ,该框架让 Objective-C 和 JavaScript 代码直接的交互变得越发的简朴轻易 ,实在就是基于 webkit 中以C/C++完成的 JavaScriptCore 的一个 OC 版本的封装 。

JavaScriptCore 和 JavaScriptCore 框架是差别的两个观点 ,能够本身理解下 。

OC 挪用 JS 代码

// 直接实行js代码
JSContext *cxt = [JSContext new];
JSValue *val =  [cxt evaluateScript:@"(function ocCallJS() { return 'ocCallJS'})()"];
NSLog(@"%@",[val toString]); // ocCallJS

// 注册js要领,运用JSValue挪用
JSContext *cxt = [JSContext new];
JSValue *jsFunction = [cxt evaluateScript:@" (function(arg) { return arg })"];
JSValue *val = [jsFunction callWithArguments:@[@"hello objc"]];
NSLog(@"%@",[val toString]); // hello objc

这里有几个对象理解下

JSContext

JSContext 对象示意 JavaScript 实行环境 ,一切 JavaScript 实行发作在上下文 , 一切 JavaScript 值中与上下文联络在一同 。

JSValue

JSValue 实例是对 JavaScript 值的包装 ( 援用 ) ,您能够运用 JSValue 类在 JavaScript 和 Objective-C 或 Swift 示意之间转换基础值(比方数字和字符串),以便在本机代码和 JavaScript 代码之间通报数据。您还能够运用此类建立 JavaScript 对象,这些对象包括自定义类或 JavaScript 函数的本机对象,这些函数的完成由本机要领或块供应。

JS 挪用 OC 代码

Block 体式格局

// 注册一个 oc 要领给 js 挪用
JSContext *cxt = [JSContext new];
cxt[@"nativeMethod"] = ^(NSString *msg) {
  NSLog(@"%@",msg);    //  jsCallOC
};
// js 挪用 oc 的要领
[cxt evaluateScript:@"nativeMethod('jsCallOC')"];  

JSExport体式格局

// 定义类 暴露给 js
@protocol JSBridgeObjProtocol <JSExport>
- (NSString *)fetchArticleContent;
@end

@interface JSBridgeObj : NSObject<JSBridgeObjProtocol>
@property (nonatomic, copy) NSString *articleTitle;
- (NSString *)fetchArticleContent;
@end

@implementation JSBridgeObj
- (NSString *)fetchArticleContent {
    return @"js call oc";
}
@end

// js 挪用 oc 要领
JSContext *cxt = [JSContext new];
cxt[@"jsBridge"] = [JSBridgeObj new];
JSValue *val = [cxt           evaluateScript:@"jsBridge.fetchArticleContent()"];
NSLog(@"%@",[val toString]); // js call oc

JXExport 完成的协定将 OC 类及实在例要领,类要领和属性导出到 JavaScript 代码

如许基于 JSContext 我们能够完成两种言语间通讯

Hybrid 中的运用

APP 夹杂开辟中 ,在 UIWebView 中猎取 JSContext 对象 ,该操纵借用了苹果的私有要领 。

// 猎取当前 WebView 的 JS 上下文
JSContext *context=[webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];

不过该要领猎取 JS 上下文有几个问题:

1 ) 猎取 JS 上下文的机遇不确定 ,比方建立 UIWebView 对象 ,UIWebView 差别代办回调要领中猎取到 JS 上下文都是不一样的 ,而且每次加载一个新的 URL 时 , 都邑废弃旧的 JS 上下文 ,建立新的 JS 上下文 。

因而猎取 JS 上下文的时候点很主要 ,也就是在方才建立好新的 JS 上下文那一刻 。

只不过苹果并没有在 iOS 的 SDK 中暴露出来 ,而 macOS 的 SDK 中有猎取建立好的 JS 上下文的代办要领。

webView:didCreateJavaScriptContext:forFrame:

在 GitHub 上有如许一个项目 TS_JavaScriptContext 能够拿到了 JS 上下文建立的事宜 ,只不过也是改猎取要领也是苹果的私有 API , 本来项目中运用了这个库上架苹果运用市肆没有问题 ,如今考核状况不太相识 。

2 ) WKWebView 现在我还没有找到猎取 JS 上下文的要领

在 UIWebView 中猎取 JS 上下文的要领在 WKWebView 中是不起作用的 。

WKWebView 不支持 JavaScriptCore 的体式格局, 但供应 messagehandler 的体式格局为 JS 与 OC 通讯 。关于 WKWebView 相干学问 ,后续再聊 。

迎接关注民众号:dreamlee,你的生长我们一同见证!

    原文作者:程序员BANG
    原文地址: https://segmentfault.com/a/1190000018985535
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞