OC与JS交互实际使用后的学习总结
公司接手了一个要和web前端交互的app项目,在这里就只是总结一下两端是怎么互相调用方法
简述:
iOS原生应用和web页面的交互大致上有这几种方法iOS7之后的
JavaScriptCore
、拦截协议
、第三方框架WebViewJavaScriptBridge
、iOS8之后的WKWebView
,在这里主要讲解JavaScriptCore
这种办法。因为经过学习感觉JavaScriptCore
使用起来是较为简单。而且更容易明白
iOS
iOS这边的方法名需要和前端
沟通定好,因为我这边的前端
也没有和App交互的经验,所以都是iOS
和Android
定的方法名,为了前端
的方法名统一,也为了减少前端
的麻烦,web页面
调用原生应用的方法可以用Delegate
或Block
两种方法。而我就说说Delegate
方法
JavaScriptCore的解释:
JSContext:
JS
运行的上下文环境
JSValue:JS
和OC
数据和方法交互的桥梁
JSExport:添加了JSExport
协议的协议,所规定的方法,变量等 就会对js
开放
VC里边的代码:
#import "ViewController.h"
#import <JavaScriptCore/JavaScriptCore.h>
@protocol JSObjcDelegate <JSExport>
//这是一个普通的回调方法
- (void)callTest;
//这可以从web端返回内容的方法
- (void)contentCallBack:(NSString *)content;
@end
@interface ViewController () <UIWebViewDelegate, JSObjcDelegate>
@property (nonatomic, strong) JSContext *jsContext;
@property (weak, nonatomic) IBOutlet UIWebView *webView;
@end
@implementation ViewController
#pragma mark - Life Circle
- (void)viewDidLoad
{
[super viewDidLoad];
NSURL *url = [[NSBundle mainBundle] URLForResource:@"test" withExtension:@"html"];
[self.webView loadRequest:[[NSURLRequest alloc] initWithURL:url]];
}
#pragma mark - UIWebViewDelegate
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
self.jsContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
self.jsContext[@"Ithran"] = self;
self.jsContext.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {
context.exception = exceptionValue;
NSLog(@"异常信息:%@", exceptionValue);
};
}
#pragma mark - JSObjcDelegate
- (void)callTest
{
NSLog(@"callTest");
//这会回调JS的“jSCallBack”方法
JSValue *jSCallBack = self.jsContext[@"jSCallBack"];
[picCallback callWithArguments:nil];
//这会回调JS的“SendJSContentCallBack”并且传了"hello world"过去
JSValue *sendJSContentCallBack = self.jsContext[@"sendJSContentCallBack"];
[picCallback callWithArguments:@[@"hello world"]];
}
- (void)contentCallBack:(NSString *)content
{
NSLog(@"content:%@", content);
}
@end
VC代码的说明:
自定义的代理
JSObjcDelegate
遵循了<JSExport>
之后,就能把定义在此协议里的方法暴露给web端
,然后web端
就可以通过此协议里的方法名与iOS端
进行交互,而这里的运行先后顺序为:
①webView
加载完之后,获取JS
运行的上下文,即是上边代码的jsContext
,然后添加桥梁的对象名为Ithran
(注释:桥梁的对象名可以随便取名,不过最好就是和其他两端人员沟通好才取名),
②继承了webDelegate
代理的webView
就会运行JSObjcDelegate
此代理里的方法
③然后继续调用JS
里的方法,如这里的jSCallBack
和sendJSContentCallBack
方法
web前端
web前端代码:
注释:以下代码可以让web前端
它写在需要触发这个方法的地方即可
<script>
var sendIOSContent = function(){
var content = '我来自web前端';
var contentStr = JSON.stringify({"content":content});
try{
Ithran.sendJSContentCallBack(conetntStr);
}catch(err){}
}
var jSCallBack = function(){
try{
alert('jScallBack success');
}catch(err){}
}
var sendJSContentCallBack = function(content){
try{
alert(content);
}catch(err){}
}
</script>
web前端代码简单说明:
这就给一些不太熟悉这段代码的同学讲解一下,web前端
可以通过这里的sendIOSContent
、jSCallBack
、sendJSContentCallBack
方法名来调用方法,Ithran
就是之前在VC
里定义的桥梁对象名,web前端
通过桥梁对象名来回调我们在VC
里定义的方法,而我们在VC
里可以通过JSValue
也可以调用到web前端
定义的方法名(所以我感觉这和拦截协议
有着大同小异的功能,虽然实质上是不同的),而这里的try{}catch(){}
方法是判断方法成功运行就运行,失败就输出错误信息
至此为止就完成了OC和JS的交互了
我这里因为用JavaScriptCore
就能解决我的交互问题,所以就不讲解其他的方法了,如果有兴趣的同学想学习其他的交互方式的话,我在下面提供一些参考和源代码的下载地址
拦截
WebViewJavaScriptBridge
WebViewJavaScriptBridge
就是通过封装拦截协议的第三方
WebViewJavaScriptBridge源码 GitHub的地址
WKWebView
如果有哪里描述错误了,也有请各位大大指正,谢谢