iOS下JS与原生的交互一

本篇主要讲的是UIWebView和JS的交互,在下一节会有wkWebView和JS交互的详解https://www.cnblogs.com/llhlj/p/9144110.html

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[@"octestFunc"]= ^(){
        //oc逻辑
        NSArray *array = [JSContext currentArguments];
        for (NSString *value in array) {
            NSLog(@"收到js值:%@",value);
        }
        return @"oc";//也可以没有返回值
    };
    //异常处理 当oc本地调用的js方法不存时,会打印异常信息,注意只有通过上下文调用的才会异常处理如oc调用js方式2、3
    self.jscontext.exceptionHandler = ^(JSContext* context,JSValue *exceptionValue){
        NSLog(@"异常信息:%@", exceptionValue);
    };
    
}

 

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

自定义协议

@protocol JSObjcDelegate<JSExport>//自定义协议
//自定义交互方法
-(id)getMessage:(id)msg;
@end
@interface WebViewController ()<UIWebViewDelegate,JSObjcDelegate>
@property(nonatomic,strong)UIWebView *webView;
@property(nonatomic,strong)JSContext *jscontext;
@end

设置代理

-(void)webViewDidFinishLoad:(UIWebView *)webView{
    //获取js上下文
    self.jscontext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    //设置代理
    self.jscontext[@"ios"]= self;
    //异常处理 当oc本地调用的js方法不存时,会打印异常信息,注意只有通过上下文调用的才会异常处理如oc调用js方式2、3
    self.jscontext.exceptionHandler = ^(JSContext* context,JSValue *exceptionValue){
        NSLog(@"异常信息:%@", exceptionValue);
    };
}

代理方法的实现

//代理方法的实现
-(id)getMessage:(id)message{
    NSLog(@"getMessage-------%@",message);
    return @"oc";//返回值可以没有
}

OC调用JS

-(void)callJSFunc{
    //方式1
//    NSString *jsText = [NSString stringWithFormat:@"ocCallJSFunc('%@')",@"哈哈"];
//    id value = [self.webView stringByEvaluatingJavaScriptFromString:jsText];//也可能没有返回值
//    NSLog(@"value-----%@",value);
    
    //方式2
//    JSValue *callback = self.jscontext[@"ocCallJSFunc"];
//    id value2 = [callback callWithArguments:@[@"222"]];
//    NSLog(@"value2-----%@",value2);
    //方式3
    NSString *jsText = @"ocCallJSFunc('222')";
    id value3 = [self.jscontext evaluateScript:jsText];
    NSLog(@"value3-----%@",value3);
    
}

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

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

posted @ 2017-02-22 16:07  LiLM  阅读(2202)  评论(0编辑  收藏  举报