UICWebView(OC)とJS(JavaScript)は相互作用します.

4402 ワード

  • UICWebViewのJSContextを取得する
  •   
    JSContext* context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
       context       webview context       ,  context       js    。
    
          Apple   Api  JSContext ,       JSContext       。    ,        API          。
    
    /**
        private api                 jscontext    ;     web     script,                
    
     @param unused class  WebView
     @param ctx   UIWebView   JSContext  
     @param frame  WebFrameLoadDelegate   WebKit WebFrame
     */
    - (void) webView: (id) unused didCreateJavaScriptContext: (JSContext*) ctx forFrame: (id) frame
    {
        
        NSString *frameMehtod = [NSString stringWithUTF8String:webFrameBase64Str];
        NSData *frameData = [[NSData alloc]initWithBase64EncodedString:frameMehtod options:NSDataBase64DecodingIgnoreUnknownCharacters];
        NSString *frameStr = [[NSString alloc]initWithData:frameData encoding:NSUTF8StringEncoding];
        SEL frameSelector = NSSelectorFromString(frameStr);
        //     only interested in root-level frames
        if ([frame respondsToSelector:frameSelector] && [frame parentFrame] != nil ) {
            return;
        }
        
        void (^didCreateJavaScriptContext)() = ^{
            
            for (UIWebView *webv in webviews) {
                
                NSString *webIdentifier =  [NSString stringWithFormat:@"rain_jsWebView_%lud",(NSUInteger)webv.hash];
                
                NSString *jsAddVariable = [NSString stringWithFormat:@"var %@ = '%@'",webIdentifier,webIdentifier];
                
                [webv stringByEvaluatingJavaScriptFromString:jsAddVariable];// webView          
                
                JSValue *identifierJSValue = ctx[webIdentifier];//              [ctx objectForKeyedSubscript:webIdentifier];
                
                if ([identifierJSValue.toString isEqualToString:webIdentifier]) {
                    [webv rainDidCreateJavaScriptContext:ctx];
                    return ;
                }
                
            }
            
        };
        
        if ([NSThread isMainThread]) {
            didCreateJavaScriptContext();
        }else {
            dispatch_async(dispatch_get_main_queue(), didCreateJavaScriptContext);
            
        }
        
    }
    
  • Native JS関数
  • を呼び出します.
    複数の方法:
    /*     ,      JSContext  webview      ,        */
    
    - (void)webViewDidFinishLoad:(UIWebView *)webView {
       
     [self.webView.context evaluateScript:@"jsFunction('native   js   ')"];
     
    }
    
    
    /*     ,  jscontext jsvalue   */
    - (void)webViewDidFinishLoad:(UIWebView *)webView {
        
      JSValue *jsFunctionValue = self.webView.context[@"jsFunction"];
       [jsFunctionValue callWithArguments:@[@"native   js   "]];
    
    }
    /*     :  webview  */
    - (void)webViewDidFinishLoad:(UIWebView *)webView {
        
         [self.webView stringByEvaluatingJavaScriptFromString:@"jsFunction('native   js   ')"];
    
    }
    
    
  • JS呼び出しNative方法
  • a、  block  
    self.webview.context[@"jsCallNative"] = ^(NSString *message){
      NSLog(message);
    }
     h5     jsCallNative('    Native   ')   
    
    b、  JSExport    
           JSExport  ,          JS   ,    JS                  
    
    
        JSExport   
    @protocol RainJSExportProtocol
    
    /**
     js          ,  native    
    
     @param log js          
     @param void js     native    
     @return void
     */
    JSExportAs(log, - (void)debugLog:(NSString *)message);
    
    /**
     js            
    
     @param callNative js       
     @param void js callNative         
     @return void
     */
    JSExportAs(callNative, - (void)callInterface:(NSString *)interface parameters:(NSString *)jsonStr);
    
    
    //          ,  js         :         ;
    //   -(void)myName:(NSString *)name age:(NSString *)myage height:(NSString *)myheight; js  native         native.myNameAgeHeight('name','15','172')
    
    @end
    
          RainJSExportProtocol    
    
    #pragma mark-- RainJSExportProtocol
    
    - (void)debugLog:(NSString *)message {
        
    #ifdef DEBUG
        
        NSLog(@"%@",message);
        
    #endif
        
    }
    
    - (void)callInterface:(NSString *)interface parameters:(NSString *)jsonStr {
        
        NSLog(@"interface %@  jsonStr %@",interface,jsonStr);
        
    }
    
         JS     native  :context[@"native"] = self;// self   jscontext       
    
     js       
    
    native.log('    ');
    native. callNative('     ','     ');
    
    
    デモアドレスを放出します
    更新時間:2018-06-28