iOS 原生webview与 JS 交互

2018-09-12  本文已影响0人  王洋Future

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__"

上一篇下一篇

猜你喜欢

热点阅读