iOS下JS與原生的交互一

本篇主要講的是UIWebView和JS的交互,在下一節會有wkWebView和JS交互的詳解https://www.cnblogs.com/llhlj/p/9144110.htmlhtml

JS調用原生OC

方式一:url攔截,這裏略過java

注意:在iOS中攔截到的url scheme將所有轉化爲小寫;ios

html中須要設置編碼,不然中文參數可能會出現編碼問題;web

JS用打開一個iFrame的方式替代直接用document.location的方式,document.location 有一個很嚴重的問題,就是若是咱們連續 2 次改 document.location 的話,在 delegate 方法中,只能截獲後面那次請求,前一次請求因爲很快被替換掉,因此被忽略掉。編碼

 

方式二:經過JavaScriptCore(iOS 7以後),用來作JS交互,所以JS與原生OC交互也變得簡單了許多。atom

//獲取js上下文,及本地添加js調用方法,通常狀況下都放在-(void)webViewDidFinishLoad:(UIWebView *)webView方法裏。lua

-(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方式二、3
    self.jscontext.exceptionHandler = ^(JSContext* context,JSValue *exceptionValue){
        NSLog(@"異常信息:%@", exceptionValue);
    };
    
}

 

方式三:同方式二類似,經過JSExport協議url

自定義協議spa

@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方式二、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:代替這個方法。

相關文章
相關標籤/搜索