很早之前有个项目牵扯到这块就很想写篇博客记录下这篇文章了,这阵子有个项目又刚好遇到,正好有空,记录记录。
跟web的同鞋打过交道的肯定都知道,只要是涉及双端交互就两种方案啦。
-
截取链接,一般也就通过UIWebView回调代理
shouldStartLoadWithRequest
截取固定链接然后在原生里面做相应的业务操作,实现也比较简单,当然这个方案也是一般涉及业务简单时候可以用,比如给个固定链接跳转原生界面,如果业务复杂点web要给原生传递参数或者多个参数再或者原生要操作web里面的相关业务,那就得考虑下面的方案二了。 -
JS交互,iOS7以前我们对JS的操作只有webview里面一个函数
stringByEvaluatingJavaScriptFromString
,当然也有很多人是用的这个第三方JavascriptBridge,IOS7之后,苹果可能也考虑到了这方面的需求,也很给力推出了JavaScriptCore这个框架。
通过stringByEvaluatingJavaScriptFromString 实现OC执行JS代码
stringByEvaluatingJavaScriptFromString
这个方法是UIWebView里面的方法,也是最为简单的和JS交互的方式。
-(nullable NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script;
用法比较简单,一般在代理方法- (void)webViewDidFinishLoad:(UIWebView*)webView
中使用。
- (void)webViewDidFinishLoad:(UIWebView*)webView
{
// 获取当前页面的title
NSString *title = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];
// 获取当前页面的url
NSString *url = [webView stringByEvaluatingJavaScriptFromString:@"document.location.href"];
}
JavaScriptCore
这是IOS7后苹果推出了JavaScriptCore这个框架,让原生和web界面交互非常方便了。代码是开源的JavaScriptCore 可以下载下来看看。
我们先了解下里面常见的属性和协议
- JSContext:给JavaScript提供运行的上下文环境,通过-evaluateScript:方法就可以执行一JS代码。
- JSValue:JavaScript和Objective-C数据和方法的桥梁,封装了JS与ObjC中的对应的类型,以及调用JS的API等。
- JSManagedValue:管理数据和方法的类JSVirtualMachine:处理线程相关,使用较少。
- JSExport:这是一个协议,如果JS对象想直接调用OC对象里面的方法和属性,那么这个OC对象只要实现这个JSExport协议就可以了。
OC调JS
self.context = [[JSContext alloc] init];
[self.context evaluateScript:@"function reduce(a,b) {return a-b}"];
JSValue *value = [self.context[@"reduce"] callWithArguments:@[@10, @3]];
NSLog(@"---%@", @([value toInt32])); //---7
JS调OC
JS调用OC有两个方法:block和JSExport protocol。
html实现代码
<input type="button" value="JS调用原生block实现" onclick="alert('alert');" />
<input type="button" value="JS调用原生JSExport protocol实现" onclick="native.alert('alert');" />
oc实现代码
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
self.context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
// 打印JS异常
self.context.exceptionHandler =
^(JSContext *context, JSValue *exceptionValue)
{
context.exception = exceptionValue;
NSLog(@"%@", exceptionValue);
};
// 以 block 形式关联 JavaScript function
self.context[@"alert"] =
^(NSString *alertText)
{
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:alertText message:nil delegate:nil cancelButtonTitle:@"ok" otherButtonTitles:nil, nil];
[alert show];
};
// 以 JSExport 协议关联 native 的方法
self.context[@"native"] = self;
}
当前类需要声明和实现JSExport协议
@protocol TestJSExport <JSExport>
-(void)alert:(NSString *)alertText;
@end
@interface JSCallOCViewController : UIViewController<TestJSExport>
@property (strong, nonatomic) JSContext *context;
@end
#pragma mark - JSExport Methods
-(void)alert:(NSString *)alertText
{
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:alertText message:nil delegate:nil cancelButtonTitle:@"ok" otherButtonTitles:nil, nil];
[alert show];
}
好啦,关于JavaScriptCore的基本介绍就是这样了。
参考http://www.jianshu.com/p/a329cd4a67ee
网友评论