您的位置:首页 > 移动开发

UIWebView-JSContext实现OC与JS交互

2016-05-20 17:48 633 查看
最近的项目中native APP提供基本的功能,部分业务放在h5中,为了提升交互体验,保证native中操作和webview中一致,需要提供Objective-C与javeScript的交互接口,也正因为项目支持版本IOS7,而IOS7以后使用javascriptcore.framework和h5的通信也相对以前简单了很多,不需要定义那么多的url shcema,可以直接通过javascriptcore完成Objective-C与javeScript的交互。

1.webView中JSContext的获取

使用 javascriptcore交互的核心是通过从webview中获取到当前的JSContext,在JSContext中执行对应的操作,一般情况下可以通过以下接口获取到当前页面的JSContext

_defaultContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];


如果webview中进行了不同的页面切换,就需要在每次完成新的页面加载后,刷新当前记录的JSContext,确保JSContext实时有效。

-(void)webViewDidFinishLoad:(UIWebView *)webView {

//网页加载完成调用此方法
_defaultContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
}


2.Objective-C调用javeScript

这部分比较简单,第一种方案可以直接使用

- (nullable NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script;


调用javeScript提供的接口,传参。

//假设JS中提供login函数
[webView stringByEvaluatingJavaScriptFromString:@"login('username','password')"];


第二种方案,使用JSContext获取对应的接口后,使用

- (JSValue *)callWithArguments:(NSArray *)arguments;




- (JSValue )evaluateScript:(NSString )script;

[_defaultContext evaluateScript:@"login('username','password')"];


//通过 JSContext 调用JS 方法,执行
JSValue *JSfunc =_defaultContext[@"login"];

[JSfunc callWithArguments:@[@'username',@'password']];


3.javeScript调用Objective-C

这个需要使用javascriptcore提供的JSExport,在Objective-C中实现该protocol的方法,就可以在javeScript使用到的接口了。JSExport相当于跨语言提供的protocol。

#include <JavaScriptCore/JavaScriptCore.h>
// Protocol to list bindings
@protocol JSBridgeExport <JSExport>

//为webview中提供与native一致的提示功能
- (void)showTip:(NSString *)tip;

@end

@interface JSBridge : NSObject <JSBridgeExport>
@end
@implementation JSBridge
- (void)showTip:(NSString *)tip{
[TopWindow makeToast:tip];
}

@end


首先将在当前JSContext进行类注册
_defaultContext[@"jsbridge"] = [[JSBridge alloc]init];
,然后就可以在JS中通过jsbridge调用OC提供的方法接口了。

[_defaultContext evaluateScript:@"jsbridge.showTip(\"this is a tip from webview\")"];


存在的问题

正如第一步中刷新JSContext一样,在不同页面进行刷新后的时候,都需要将OC提供给JS的方法进行注册,确保当前JS环境中提供的接口有效。

-(void)webViewDidFinishLoad:(UIWebView *)webView {

//网页加载完成调用此方法
//刷新当前记录JSContext,刷新接口
_defaultContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
_defaultContext[@"jsbridge"] = [[JSBridge alloc]init];
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息