iOS下的JS和原生的交互

JS代用原生OC

方式一:url拦截,这里略过

注意:在iOS中拦截到的url scheme将全部转化为小写;

html中需要设置编码,否则中文参数可能会出现编码问题;

JS用打开一个iFrame的方式替代直接用document.location的方式,document.location 有一个很严重的问题,就是如果我们连续 2 次改 document.location 的话,在 delegate 方法中,只能截获后面那次请求,前一次请求由于很快被替换掉,所以被忽略掉。

方式二:通过JavaScriptCore(iOS 7之后),用来做JS交互,因此JS与原生OC交互也变得简单了许多。

//获取js上下文,及本地添加js调用方法,一般情况下都放在-(void)webViewDidFinishLoad:(UIWebView *)webView方法里。

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

//获取js上下文

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

//添加js代用方法

self.jsContext[@"ocGetValueFromJS"]= ^(){

NSArray *array = [JSContext currentArguments];

for (NSString *value in array) {

NSLog(@"收到js值:%@",value);

}

};

//异常处理

self.jsContext.exceptionHandler = ^(JSContext* context,JSValue *exceptionValue){

context.exception = exceptionValue;

NSLog(@"异常信息:%@", exceptionValue);

};

}

方式三:同方式二相似,通过JSExport协议

@protocol JSObjcDelegate

-(void)getMessage:(id)msg;

@end

@interface WebViewController ()

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

//获取js上下文

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

//设置代理

self.jsContext[@"ios"]= self;

//异常检查,当oc本地调用的js方法不存时,会打印异常信息

self.jsContext.exceptionHandler = ^(JSContext* context,JSValue *exceptionValue){

context.exception = exceptionValue;

NSLog(@"异常信息:%@", exceptionValue);

};

}

//代理方法的实现

-(void)getMessage:(id)message{

NSLog(@"getMessage-------%@",message);

}

OC调用JS

方式一

NSString *jsText = [NSString stringWithFormat:@"jsGetValueFromOc('%@')",@"哈哈"];

[self.webView stringByEvaluatingJavaScriptFromString:jsText];

方式二

通过使用JavaScriptCore

JSValue *callback = self.jsContext[@"jsGetValueFromOc"];

[callback callWithArguments:@[@"222"]];

或者

NSString *jsText = @"jsGetValueFromOc('222')";

[self.jsContext evaluateScript:jsText];

注意:stringByEvaluatingJavaScriptFromString是一个同步的方法,使用它执行JS方法时,如果JS 方法比较耗的时候,会造成界面卡顿。

官方推荐使用WKWebView(ios8)的evaluateJavaScript:completionHandler:代替这个方法。

你可能感兴趣的:(iOS下的JS和原生的交互)