美文网首页
iOS 原生webview与 JS 交互

iOS 原生webview与 JS 交互

作者: 王洋Future | 来源:发表于2018-09-12 11:18 被阅读0次

    1. 加载webview:

    self.webView = [[UIWebView alloc]init];

        [self.view addSubview:self.webView];

        self.webView.frame = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height);

        // 自动对页面进行缩放以适应屏幕    

    self.webView.scalesPageToFit = YES;

        // 需要在代理方法中与js进行交互    

    self.webView.delegate = self;

        // 取消webView的弹簧效果  

      [(UIScrollView *)[[self.webView subviews] objectAtIndex:0] setBounces:NO];

        NSString *urlStr = @"http://www.baidu.com/";

        NSURLRequest *request = [[NSURLRequest alloc]initWithURL:[NSURL URLWithString:urlStr]];

    2. webview的代理方法

    // 当点击页面进行加载数据的时候调用

    - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;

    // 当页面开始加载的时候调用

    - (void)webViewDidStartLoad:(UIWebView *)webView;

    // 当页面加载完成的时候调用

    - (void)webViewDidFinishLoad:(UIWebView *)webView;

    // 页面加载失败的时候调用

    - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error;

    3.  交互

     方法一:  拦截url

    - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {

        // 获取点击页面加载的url    NSString *url = request.URL.absoluteString;

        if ([url rangeOfString:@"此处写想拦截的url字符串"].location != NSNotFound) {

            // 通过获取当前点击页面加载的url与指定url进行比较,拦截页面请求,进行自己的逻辑处理        

    // 进行移动端的逻辑处理       

     UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"" message:@"拦截页面方法" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:nil, nil];

            [alert show];

            return NO;

        }

        return YES;

    }

    方法二:注册OC与js方法

    - (void)webViewDidFinishLoad:(UIWebView *)webView {

        // 获取当前网页的标题    NSString *titleStr = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];

        NSLog(@"%@",titleStr);

        // 还可以直接调用js定义的方法    // 比如getShareUrl()为js端定义好的方法,返回值为分享的url    // 我们就可以通过调用这个方法在returnStr中拿到js返回的分享地址    

    NSString *returnStr = [webView stringByEvaluatingJavaScriptFromString:@"getShareUrl()"];

        NSLog(@"%@",returnStr);

        // 还可以为js端提供完整的原生方法供其调用(记得导入#import )   

     JSContext *context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];

        // 可以定义供js调用的方法, testMethod为js调用的方法名    

    context[@"testMethod"] = ^() {

            dispatch_async(dispatch_get_main_queue(), ^{

                UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"" message:@"js调用方法" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:nil, nil];

                [alert show];

            });

        };

    方法三:桥接机制

    OC和JS交互的桥接机制,主要包含3个类,JS端window.WebViewJavascriptBridge,OC端WebViewJavascriptBridge和WebViewJavascriptBridgeBase。

    桥接类支持JS调用OC方法,OC调用JS方法。JS调用OC通过重定向url并取handlerName来调用,OC调用JS通过stringByEvaluatingJavaScriptFromString调用。

    // jsBridge

        [WebViewJavascriptBridge enableLogging];

        // 给哪个webview建立JS与OjbC的沟通桥梁

        WebViewJavascriptBridge  *webViewJSBridge = [WebViewJavascriptBridge bridgeForWebView:webViewS];

        [webViewJSBridge setWebViewDelegate:self];

        /* JS主动调用OjbC的方法 -

         * 这是JS会调用saveUserAccountAndPassword方法,这是OC注册给JS调用的

         * JS需要回调,当然JS也可以传参数过来。data就是JS所传的参数,不一定需要传

         * OC端通过responseCallback回调JS端,JS就可以得到所需要的数据

         */

        [webViewJSBridge  registerHandler:@"saveUserAccountAndPassword"handler:^(id data,WVJBResponseCallback  responseCallback) {

            NSLog(@"js call saveUserAccountAndPassword, data from js is %@", data);

           NSDictionary*userDict = (NSDictionary*)data;

            [[FSDataShareManger shareDataManger] saveUserModelWithCache:userDict];

        }];

     /* OC主动调用JS的方法 

         */

    [webViewJSBridge  callHandler:@"getUserInfos"   data:@{@"name":@"标哥"}   responseCallback:^(idresponseData){

    NSLog(@"from js: %@",responseData);

    }];

    注意:

    /*这段代码是固定的,必须要放到js中*/

    functionsetupWebViewJavascriptBridge(callback){

    if(window.WebViewJavascriptBridge){returncallback(WebViewJavascriptBridge);}

    if(window.WVJBCallbacks){returnwindow.WVJBCallbacks.push(callback);}

    window.WVJBCallbacks=[callback];

    varWVJBIframe=document.createElement('iframe');

    WVJBIframe.style.display='none';

    WVJBIframe.src='wvjbscheme://__BRIDGE_LOADED__';        

    document.documentElement.appendChild(WVJBIframe);

    setTimeout(function(){document.documentElement.removeChild(WVJBIframe)},0)

    }

    注意:  找问题时候用

    iOS中WebViewJavascriptBridgeBase中的和  WVJBIframe.src='wvjbscheme://__BRIDGE_LOADED__';  对比一下

    #define kOldProtocolScheme @"wvjbscheme"

    #define kNewProtocolScheme @"https"

    #define kQueueHasMessage  @"__wvjb_queue_message__"

    #define kBridgeLoaded      @"__bridge_loaded__"

    相关文章

      网友评论

          本文标题:iOS 原生webview与 JS 交互

          本文链接:https://www.haomeiwen.com/subject/gcxvgftx.html