iOS UIWebView interacts natively with JS

It is a very common logic to use webView to load web pages in iOS development. Sometimes we intercept js methods in webView to make our own logical judgments, and sometimes we need to provide some native methods for js. Make a call, or call some js methods to modify the logic of the page after the page is loaded.

First load the 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]];

Then we look at the four proxy methods of UIWebView

// 当点击页面进行加载数据的时候调用
- (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;

From these four proxy methods, we can see that the shouldStartLoadWithRequest method will be called every time we click on the page to load data, so we can intercept the js method in this method and replace it with our own method

- (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;
}

Another method is to inject or call the js method after the page is loaded to modify the original interface logic, or define a native method for js to call directly. Note that the logic below must be called after the page is loaded.

- (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 <JavaScriptCore/JavaScriptCore.h>)
    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];
        });
    };
}

Through the above methods, we can realize almost all the logic that interacts with js in our development.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325981681&siteId=291194637