OC與JS交互基于JavaScriptCore(UIWebView)

準(zhǔn)備工作:
1.在創(chuàng)建UIWebView的類中,導(dǎo)入頭文件:
#import <JavaScriptCore/JavaScriptCore.h>
2.在webView的代理方法中的任意一個(gè)方法中創(chuàng)建JSContext對(duì)象,我一般是在finisLoad里面創(chuàng)建

代理方法
-(void)webViewDidStartLoad:(UIWebView *)webView;
-(void)webViewDidFinishLoad:(UIWebView *)webView;

創(chuàng)建JSContext對(duì)象:


-(void)webViewDidFinishLoad:(UIWebView *)webView{
    __weak typeof(self) weakSelf = self;
    //創(chuàng)建JSContext上下文對(duì)象
     JSContext *context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    //監(jiān)聽地理位置     @“getPaymetCertAuthMsg”  這個(gè)就是JS提供的方法,供OC調(diào)用
    _context[@"getPaymetCertAuthMsg"] = ^() {
        NSLog(@"當(dāng)前線程:%@",[NSThread currentThread]);

    };
   
}
  //監(jiān)聽返回按鈕
    Phone *phone = [Phone new];
    phone.block = ^{
        dispatch_async(dispatch_get_main_queue(), ^{
              [self.navigationController popViewControllerAnimated:YES];
        });
    };
    _context[@"Phone"] = phone;

一. OC調(diào)用JS方法:JS提供一個(gè)方法供OC調(diào)用

在OC調(diào)用JS的方法中,如果我們需要傳遞多個(gè)參數(shù),第一種就是我下面寫的這樣的,多個(gè)參數(shù)分開寫,還有一個(gè)就是封裝成json,然后傳過去

例如:

假數(shù)據(jù): NSSting *strData = @" {
      "name" : "lxy"
      "age" :  17
}"

NSString *jsStr1 = [NSString stringWithFormat:@"recPaymetCertAuthMsg('%@')",strData];
[weakSelf.webView stringByEvaluatingJavaScriptFromString:jsStr1];
JS的方法名是: recPaymetCertAuthMsg

方式1:不依賴JavaScriptCore。主要調(diào)用:stringByEvaluatingJavaScriptFromString 這個(gè)方法。
如下

NSString *jsStr1 = [NSString stringWithFormat:@"recPaymetCertAuthMsg('%@','%@','%@','%@','%@','%@','%@','%@','%@','%@','%@','%@')",isloca,@"2",latitude,longitude,ipStr,@"",iMei,@"",ipType,@"",phoneType,phoneStr ];
[weakSelf.webView stringByEvaluatingJavaScriptFromString:jsStr1];

方式2:依賴JavaScriptCore。主要調(diào)用:evaluateScript 這個(gè)方法。
如下

  
NSString *jsStr1 = [NSString stringWithFormat:@"recPaymetCertAuthMsg('%@','%@','%@','%@','%@','%@','%@','%@','%@','%@','%@','%@')",isloca,@"2",latitude,longitude,ipStr,@"",iMei,@"",ipType,@"",phoneType,phoneStr ];
[weakSelf.context evaluateScript:jsStr1];

二.JS調(diào)用OC方法

方式1:利用:JSContext 如下
在創(chuàng)建完JSContext對(duì)象之后,當(dāng)JS方法調(diào)用window.getPaymetCertAuthMsg()時(shí), OC中就會(huì)走到下面方法中的For循環(huán)那里
所以JS調(diào)用OC的核心代碼就是:

  JSContext *context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    //監(jiān)聽地理位置     @“getPaymetCertAuthMsg”  這個(gè)就是JS提供的方法,供OC調(diào)用
    _context[@"getPaymetCertAuthMsg"] = ^() {
//如果JS方法還有返回值,則會(huì)在下面的打印中打印出來。
      NSArray *array = [JSContext currentArguments];
      for(JSValue * str in array){
           NSLog(@"從js代碼傳入的值:%@",str.toString);
    };

方式二:利用JavaScriptcore的協(xié)議<JSExport>:
在進(jìn)行這種交互方式之前,我們先要和JS開發(fā)者確認(rèn)一件事情,那就是調(diào)用JS方法時(shí)候的類是哪個(gè)類,需要一個(gè)類名字符串
我舉個(gè)栗子:
假如JS定義為: Phone.gotoBack() 這樣一個(gè)方法。
那么我們首先就要在OC代碼里面先創(chuàng)建一個(gè)命名為Phone的類
如下截圖:

圖片.png

再接著需要在這個(gè)類里面創(chuàng)建一個(gè)繼承<JSExport>的協(xié)議,并實(shí)現(xiàn)協(xié)議中的方法

在 #import"Phone.h"  中寫入下面的協(xié)議

@protocol PhoneDelegate <JSExport>
-(void)gotoBack:(NSString *)url;
@end

在 #import"Phone.m"  中實(shí)現(xiàn)和JS定義好的方法:gotoBack

-(void)gotoBack:(NSString *)url{
    NSLog(@"Phone:%@",url);
//URL為JS傳過來的參數(shù),類型為字符串,如果有多個(gè)參數(shù),則封裝為JSON字符串過來,然后再解析取出對(duì)應(yīng)數(shù)據(jù)   
    if ([url isEqualToString:@"backZJBank"]) {
      //do some thing
    }
}

使用Phone的方式:

-(void)webViewDidFinishLoad:(UIWebView *)webView{
    __weak typeof(self) weakSelf = self;
    //創(chuàng)建JSContext上下文對(duì)象
     JSContext *context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
  //監(jiān)聽返回按鈕
    Phone *phone = [Phone new];
    phone.block = ^{
        dispatch_async(dispatch_get_main_queue(), ^{
              //返回上一層控制器
             [self.navigationController popViewControllerAnimated:YES];
        });
    };
    _context[@"Phone"] = phone;
}
注:當(dāng)JS調(diào)用gotoBack方法時(shí),Phone類中的-(void)gotiBack:(NSSting *)url;方法就會(huì)被調(diào)用

3.攔截URL的方式進(jìn)行交互

在webView的代理方法中,攔截URL進(jìn)行交互

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
    NSString *ab = request.URL.absoluteString;
    NSLog(@"攔截到的連接URL:%@",[request.URL scheme]);
    [self hoadUpUrlInWebView:ab];
    return YES;
}

//攔截特定的URL,然后做相應(yīng)的處理
-(void)hoadUpUrlInWebView:(NSString *)urlStr{
//自定義的協(xié)議頭,然后進(jìn)入相應(yīng)的判斷邏輯里
    NSString *scheme = @"zxbank://direct.grcbank.com";
    //如果包含這個(gè)字符串,則進(jìn)入判斷邏輯處理
    if ([urlStr hasPrefix:scheme]) {
    //自定義的相應(yīng)功能的字符串@“takePhoto”
        if([urlStr containsString:@"takePhoto"]){
     //進(jìn)入到相應(yīng)功能,比如拍照
        }
}
由于時(shí)間原因,我沒有帖出來JS代碼部分,等有時(shí)間補(bǔ)上。不明白的可以評(píng)論 我會(huì)及時(shí)回復(fù)的。如果由于不知道JS那邊是什么樣子的被卡住了,可以評(píng)論提出來,我來為您解答。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容