iOSとJavaScriptの相互作用

10491 ワード

方案一:伝統的なインタラクション
利点:ページのロードが完了するまで待つ必要はなく、該当するコードが実行されるとOCを呼び出すことができる方法(JavaScripptCoreと比較して)欠点:文字列を複雑に説明して対応する方法名と送信値を得る必要があり、呼び出しの方法もリターン値を伝えることができません.
1、OC呼び出しJSstringByEvaluatingJavaScriptFromString方法を使用して、javascriptをページに埋め込むことができます.UICWebViewのページの読み込みが完了したら呼び出す必要があります.
- (void)viewDidLoad{
    [super viewDidLoad];
    webview.backgroundColor = [UIColor clearColor]; 
    webview.scalesPageToFit =YES;
    webview.delegate =self;
    NSURL *url =[[NSURL alloc] initWithString:@"https://www.google.com.hk"];

    NSURLRequest *request =  [[NSURLRequest alloc] initWithURL:url];
    [webview loadRequest:request];   
}
//1、OC   JS   , webViewDidFinishLoad        javascript      
 - (void)webViewDidFinishLoad:(UIWebView *)webView {  
    //1.1、       url
    NSString *currentURL = [webView stringByEvaluatingJavaScriptFromString:@"document.location.href"];
    //1.2、       title
   NSString *title = [webview stringByEvaluatingJavaScriptFromString:@"document.title"]; 
    //1.3、        (       google     :“Terence”   。)
    NSString *js_result = [webView stringByEvaluatingJavaScriptFromString:@"document.getElementsByName('q')[0].value='Terence';"];
    //1.4、    
    NSString *js_result2 = [webView stringByEvaluatingJavaScriptFromString:@"document.forms[0].submit(); "];
    //1.5、  js  (              js   ,             ,    :)
    // a、    js    script   ,type 'text/javascript'。
    // b、               ,           :myFunction,      google          。
    // c、    stringByEvaluatingJavaScriptFromString  myFunction  。
    [webView stringByEvaluatingJavaScriptFromString:
        @"var script = document.createElement('script');" 
         "script.type = 'text/javascript';" 
         "script.text = \"function myFunction() { " 
         "var field = document.getElementsByName('q')[0];" 
         "field.value='Terence';" 
         "document.forms[0].submit();" 
         "}\";" 
         "document.getElementsByTagName('head')[0].appendChild(script);"//   head  
    ];
    [webView stringByEvaluatingJavaScriptFromString:@"myFunction();"];
    
    //2.1、  JS     
    [webView stringByEvaluatingJavaScriptFromString:@"clickme();"]; 
    //2、OC   JS      
    NSString *value = @“      ”;
    [self.webView stringByEvaluatingJavaScriptFromString:@“transValue(‘%@‘)”,value];  
 }  
  
  
       
         html      
       
         function clickme() {  
             alert('     !');  
         }  
         function transValue(insert) {  
             alert(insert);  
         }  
       
   
   
     

OC JS

2、JS呼び出しOC
webViewブロックurlリンクは、カスタムプロトコルの内容を取得し、結果を処理します.
//JS   
function sendToOC(){
    var para1 = document.getElementById("element1").value;
    var para2 = document.getElementById("element2").value;
    //  "gallery://"       ;para1&para2    OC  , ","    
    var url = "gallery://"+para1+","+para2;
    document.loc ation = url;
}     
//  UIWebViewDelegate    。
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
    //       url
    NSString *requestStr = [[request.URL absoluteString] stringByRemovingPercentEncoding];
    // url         "gallery://"
    if ([requestStr hasPrefix:@"gallery://"]) {
        //  "://"    url      ,    arr
        NSArray *arr = [requestStr componentsSeparatedByString:@"://"];
        //         
        NSString *paramStr = arr[1];
        // ","       url       ,    
        NSArray *paraArray = [paramStr componentsSeparatedByString:@","];

        //    ,    
        if (paraArray.count) {
            NSLog(@"   ");
            [self doSomeThingWithParamA:paraArray[0] andParamB:paraArray[1]];
        }else{
            NSLog(@"   ");
        }
        return NO;
    }

    return YES;
}
// JS        
- (void)doSomeThingWithParamA:(id)paramA andParamB:(id)paramB{
    NSLog(@"para1:%@--para2:%@", paramA, paramB);
}
案二:JavaScriptCore.frameworkフレーム
利点:アップルの公式フレームは、シンプルで効率的です.短所:OC JSの呼び出しは、HTMLのロードが完了するまで待つ必要があります.
1、OC呼び出しJS
 //             
-(void)webViewDidFinishLoad:(UIWebView *)webView  
{  
    //    JSContext   (      webView     jscontext)  
    JSContext *context=[webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];  
    //     js  
    NSString *alertJS=@"alert('test')";   
    //  oc    js alert( webview    ,    js  )  
    [context evaluateScript:alertJS];
} 
2、JS呼び出しOC
#import 

-(void)webViewDidFinishLoad:(UIWebView *)webView{
    // 1.    
    JSContext *jsContext = [webView     valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    // 2.    
    jsContext.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {
        context.exception = exceptionValue;
        NSLog(@"    :%@", exceptionValue);
    };
    // 3.    (sendFunc,sendParam  JS      )
    //    
    jsContext[@"sendFunc"] = ^{
        NSArray *args = [JSContext currentArguments];
        for (id obj in args){
            NSLog("parameter:%@",obj);
        }
    }
    //        
    jsContext[@"sendParam"] = ^(NSDictionary *dic){
        NSLog("params:%@",dic);
    }
}
//  jsendToOC  js    ,  args     js     , js   oc   。
jsコード:
function onClick(){
    var para1 = document.getElementById("element1").value;
    var para2 = document.getElementById("element2").value;    
            
    sendFunc(para1,para2);
}
//     

      OC    ,     click  ,    sendToOC    。
案3:WebViewJavascriptBridge第三のフレーム(githubアドレス)
WebView JavascriptBridgeはUID WeViewとWKWebViewを同時にサポートしています.JSがOCを呼び出しても、OCがJSを呼び出しても、正常な値と戻り値ができます.また、ページにロードする時はJSコードが実行されている限り、相互作用ができます.上記の2つの案の欠点がないので、今は相互作用を処理する主流のやり方です.

function setupWebViewJavascriptBridge(callback) {
    if (window.WebViewJavascriptBridge) { return callback(WebViewJavascriptBridge); }
    if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); }
    window.WVJBCallbacks = [callback];
    var WVJBIframe = document.createElement('iframe');
    WVJBIframe.style.display = 'none';
    WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__';
    document.documentElement.appendChild(WVJBIframe);
    setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0)
}


setupWebViewJavascriptBridge(function (bridge){
    //OC   JS 'wevViewJSHandler'             ;'data' OC     ;'responseCallback' JS      OC   
    
    bridge.registerHandler('webViewJSHandler', function(data, responseCallback) {
        //  OC     
        log('ObjC called wevViewJSHandler with', data)
        var responseData = { 'Javascript Says':'Right back atcha!' }
        log('JS responding with', responseData)
        //   ,     oc
        responseCallback(responseData)
    })
    
    var callbackButton = document.getElementById('buttons').appendChild(document.createElement('button'))
        callbackButton.innerHTML = '   ,    oc   '
        callbackButton.onclick = function(e) {
            e.preventDefault()                                 
            
            bridge.callHandler('loginAction', {'userId':'zhangsan','name': '  '}, function(response) {
                 //  oc     
                 alert('  oc     :'+response)
            })
        }
    })
}
#immport "WebViewJavascriptBridge.h"
-(void)viewDidLoad{
    [super viewDidLoad];
    //1.     WebViewJavascriptBridge
    if (_bridge) { return; }
    [WebViewJavascriptBridge enableLogging];    //     Bridge    
    _bridge = [WebViewJavascriptBridge bridgeForWebView:webView];
    [_bridge setWebViewDelegate:self];    //  bridge  
    
    //    html,  :  h5   ,         oc   
    [self loadExamplePage:webView];    
    
    //  js  oc       ,     ,h5       ,oc      
    [self JS2OC];    
  
    //    :2  ,oc   js   
    //  :      ,       html    ,    oc     ;  ,webview request             (      [self loadExamplePage:webView]  [self OC2JS]    ,      )
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self OC2JS];        
    });
}
//JS    OC
-(void)JS2OC{
    /*
       :JS  OC
     @param registerHandler         (       loginAction)
     @param handel   block                  block     
     */
    [_bridge registerHandler:@"loginAction" handler:^(id data, WVJBResponseCallback responseCallback) {
        // data js                     ,    
        NSLog(@"JS  OC,     ");
        
        //   data         
        NSDictionary *dict = (NSDictionary *)data;
        NSString *str = [NSString stringWithFormat:@"   :%@    :%@",dict[@"userId"],dict[@"name"]];
        [self renderButtons:str];
        
        // responseCallback  js   
        responseCallback(@"  ,oc   js   ");
    }];
}

//OC    JS
-(void)OC2JS{
    /*
       :OC  JS
     @param callHandler        ,               
     @param data id  ,           ,              
       ,  callHandler 3 ,                            
     */
    
    //[_bridge callHandler:@"registerAction" data:@"  oc  js   "];
    [_bridge callHandler:@"registerAction" data:@"uid:123 pwd:123" responseCallback:^(id responseData) {
        NSLog(@"oc  js        :%@",responseData);
    }];
}
     :OC JS         ,       。