js与OC互相调用 —— UIWebview拦截Url

简单整理了下在ios编译环境下,oc与js相互调用通过UIWebview拦截url,达到实现效果。
1.创建本地html文件


html文件.png

2.创建UIWebview

 self.webView = [[UIWebView alloc] initWithFrame:self.view.frame];
    self.webView.delegate = self;
    NSURL *htmlURL = [[NSBundle mainBundle] URLForResource:@"index.html" withExtension:nil];
//    NSURL *htmlURL = [NSURL URLWithString:@"http://www.baidu.com"];
    NSURLRequest *request = [NSURLRequest requestWithURL:htmlURL];
    
    // 如果不想要webView 的回弹效果
    self.webView.scrollView.bounces = NO;
    // UIWebView 滚动的比较慢,这里设置为正常速度
    self.webView.scrollView.decelerationRate = UIScrollViewDecelerationRateNormal;
    [self.webView loadRequest:request];
    [self.view addSubview:self.webView];

3.通过UIWebViewDelegate代理方法拦截Url

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    NSURL *URL = request.URL; // haleyaction://scanClick

    NSString *scheme = [URL scheme]; // haleyaction
    if ([scheme isEqualToString:@"haleyaction"]) {
        [self handleCustomAction:URL];
        return NO;
    }
    
    return YES;
}

通过判断scheme判断实现不同的方法

- (void)handleCustomAction:(NSURL *)URL
{
    NSString *host = [URL host];
    if ([host isEqualToString:@"scanClick"]) {
        NSLog(@"扫一扫");
    } else if ([host isEqualToString:@"shareClick"]) {
        [self share:URL];
    } else if ([host isEqualToString:@"getLocation"]) {
        [self getLocation];
    } else if ([host isEqualToString:@"setColor"]) {
        [self changeBGColor:URL];
    } else if ([host isEqualToString:@"payAction"]) {
        [self payAction:URL];
    } else if ([host isEqualToString:@"shake"]) {
        [self shakeAction];
    } else if ([host isEqualToString:@"goBack"]) {
        [self goBack];
    }
}

回调结果到js中

- (void)getLocation
{
    // 获取位置信息
    // 将结果返回给js
    NSString *jsStr = [NSString stringWithFormat:@"setLocation('%@')",@"广东省深圳市南山区学府路XXXX号"];
    [self.webView stringByEvaluatingJavaScriptFromString:jsStr];
}

在js中把参数传给OC

  function shareClick() {
                loadURL("haleyAction://shareClick?title=测试分享的标题&content=测试分享的内容&url=http://www.baidu.com");
            }

获取传递过来的参数,通过相关重要参数分割,组成新的字典

- (void)share:(NSURL *)URL
{
    // URL.query ===》 title=%E6%B5%8B%E8%AF%95%E5%88%86%E4%BA%AB%E7%9A%84%E6%A0%87%E9%A2%98&content=%E6%B5%8B%E8%AF%95%E5%88%86%E4%BA%AB%E7%9A%84%E5%86%85%E5%AE%B9&url=http://www.baidu.com
    NSArray *params =[URL.query componentsSeparatedByString:@"&"];
    /*
     <__NSArrayM 0x60400044af80>(
     title=%E6%B5%8B%E8%AF%95%E5%88%86%E4%BA%AB%E7%9A%84%E6%A0%87%E9%A2%98,
     content=%E6%B5%8B%E8%AF%95%E5%88%86%E4%BA%AB%E7%9A%84%E5%86%85%E5%AE%B9,
     url=http://www.baidu.com
     )
     */
    NSMutableDictionary *tempDic = [NSMutableDictionary dictionary];
    for (NSString *paramStr in params) {
        NSArray *dicArray = [paramStr componentsSeparatedByString:@"="];
        if (dicArray.count > 1) {
            NSString *decodeValue = [dicArray[1] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
            [tempDic setObject:decodeValue forKey:dicArray[0]];
            /*
             
             (lldb) po tempDic
             {
             content = "\U6d4b\U8bd5\U5206\U4eab\U7684\U5185\U5bb9";
             title = "\U6d4b\U8bd5\U5206\U4eab\U7684\U6807\U9898";
             url = "http://www.baidu.com";
             }
             
             */
        }
    }
    
    NSString *title = [tempDic objectForKey:@"title"];
    NSString *content = [tempDic objectForKey:@"content"];
    NSString *url = [tempDic objectForKey:@"url"];
    // 在这里执行分享的操作
    
    // 将分享结果返回给js 划重点
    NSString *jsStr = [NSString stringWithFormat:@"shareResult('%@','%@','%@')",title,content,url];
    [self.webView stringByEvaluatingJavaScriptFromString:jsStr];
}

OC调用JS方法


oc调用Js方法.png

在OC中的方法调用

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
   [webView stringByEvaluatingJavaScriptFromString:@"var arr = [3, 4, 'abc'];"];
}

实现效果


js与oc交互.gif

注意事项

如果回调执行的JS 方法带参数,而参数不是字符串时,不要加单引号,否则可能导致调用JS 方法失败。比如我这样的:

NSData *jsonData = [NSJSONSerialization dataWithJSONObject:userProfile options:NSJSONWritingPrettyPrinted error:nil];
NSString *jsonStr = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSString *jsStr = [NSString stringWithFormat:@"loginResult('%@',%@)",type, jsonStr];
[_webView stringByEvaluatingJavaScriptFromString:jsStr];
如果第二个参数用单引号包起来,就会导致JS端的loginResult不会调用。

注意要点在oc中调用js中方法,方法名称和参数均要一一对应。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容