浅尝一下IOS JSB
一.前言
前端经常说 JSB ,但 JSB 到底是什么?
我们常说的跨端通信,前端和客户端(IOS、安卓)的通信方案,前端常说的两种方式:注入式、拦截式。
但实际上对客户端来说,方式有很多。以IOS为例,方案有IOS7之后的JavaScriptCore框架、iOS8之后的WKWebView、拦截协议、基于拦截协议封装的第三方框架WebViewJavaScriptBridge。
各大公司都有一套自己的JSB机制,腾讯的JSB API,字节的鹊桥等等。实现的本质都是通过抹平了端API差异,前端只调用同一个API即可调用双端能力。端通信的通用API比如前端调用sendEventMessage(eventName,params)来实现跨端通信,三端进行监听eventName执行对应操作。
今晚上突然心血来潮,本来是想实现一个通信机制的 demo 的。
但最终只是实现了跨端通信能力,IOS方案是JavaScriptCore,注入前端的window中。
太困了,简单写一下就睡了,明天还要搬砖。
二.手撕代码
项目地址:https://github.com/lxhguard/iosJsbLearnApp
这个项目是一晚上手写的,OC的设计我真是吐了,一个BUG我检查老半天,还有功能代码的设计好绕啊。
《黑客与画家》:评价一种语言的优劣,不能简单地看最后的程序是否表达得很漂亮,而要看程序从无到有的那条完成路径是否很漂亮。某种设计使得最后的程序非常漂亮,但是不一定同时具备漂亮的编程过程。
我简单说下,这个项目要关注什么吧。项目里我写了丰富的注释,基本能一眼看懂。
重点关注文件有两个:(1)iosLearnApp/ViewController.m (2)www/index.html
前者是客户端逻辑文件,后者是大家熟悉的前端文件。先说前者,再说后者。
自定义 JSObjcDelegate 协议,而且此协议必须遵守JSExport这个协议,自定义协议中的方法就是暴露给web页面的方法。这里有个点要注意一下,就是NSLog是在主线程中运行的,而下面的代码是在子线程中运行的。他们虽然在同一个函数体里,但运行在不同的线程。
OC 强类型语言,和 Java 写起来很像,先定义接口,再去实现。
@protocol JSObjcDelegate <JSExport>
- (void)getMsgFromFS:(NSString *)infoStr;
@end
- (void)getMsgFromFS:(NSString *)infoStr {
NSLog(@"getMsgFromFS infoStr:%@", infoStr);
NSDictionary *info = [self dictionaryWithJsonString:infoStr];
NSDictionary *params = info[@"params"];
NSLog(@"getMsgFromFS params:%@", params);
_label.text = params[@"desc"];
那IOS是怎么实现前端所谓的注入式的呢?就很简单,直接调用JSCore的框架能力。
JSCore相关的东东,我之前大三写过 「Webkit」的文章,投稿在「脑洞前端」,在我的公众号里转发了一下,感兴趣的在号内搜索看下。
#pragma mark - UIWebViewDelegate
/** Webview 加载完成时,打通IOS、前端之间的数据通信
前端角度:进行注入式JSB,即通过 WebView 提供的接口向 window 中注入对象或方法
客户端角度:使用苹果推出的JavaScriptCore框架进行跨端通信