zoukankan      html  css  js  c++  java
  • 金刚娃谈UIWebView与JS交互

    1.JS调用OC的方法   

    OC自定义一个协议 例如YBHTTP:。JS遵循这个协议,发出一个请求window.location.href='YBHTTP:http://www.baidu.com'

    OC在

    - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType 这个代理方法中拦截该请求  并根据之前规定好的协议解析这个请求,这样就知道JS要OC做什么事情,然后OC在做相应的事。相关代码仅供参考

    #define kJSCallOCRequestDataHeader @"YBHTTP:" //js调用oc方法请求数据的协议头

    #define kJSCallOCWebSocketHeader @"websocket:" //js调用oc方法 websocket相关

    先说明一下 kJSCallOCRequestDataHeader  kJSCallOCWebSocketHeader是定义好的宏   JSCallOCProtocol是我自己定义的一个模型  [JS_OC JSCallObjcWithJSCallOCProtocol:jsCallOCProtocol webView:webView]这个是我解析协议之后我OC要做的事

    下面的代码解析了两个协议 

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

    {

        NSString *url = [request.URL.absoluteString stringByRemovingPercentEncoding];

        YBLog(@"%@", url);

        if ([url hasPrefix:kJSCallOCRequestDataHeader])//判断url是否遵循了JS调用OC方法 请求数据协议

        {

            NSString *json = [url substringFromIndex:kJSCallOCRequestDataHeader.length];

            NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:[json dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingAllowFragments error:nil];

            NSString *url = [jsonDict[@"url"] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

            NSString *method = [jsonDict[@"method"] lowercaseString];

            NSString *callback = jsonDict[@"callback"];

            NSDictionary *parameters = jsonDict[@"parameters"];

            JSCallOCProtocol *jsCallOCProtocol = [JSCallOCProtocol jsCallOCProtocolWithURL:url method:method callback:callback parameters:parameters];

            [JS_OC JSCallObjcWithJSCallOCProtocol:jsCallOCProtocol webView:webView];//JS调用OC的方法  这个是我自己自定义的  方法

            return NO;//禁止加载该页面

        }

        else if ([url hasPrefix:kJSCallOCWebSocketHeader])//js调用oc  websocket相关方法

        {

            NSString *json = [url substringFromIndex:kJSCallOCWebSocketHeader.length];

            NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:[json dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingAllowFragments error:nil];

            NSString *type = jsonDict[@"type"];

            NSString *callback = jsonDict[@"callback"]; //js的回调方法

            

            if ([type isEqualToString:@"getCurrentMessageCount"])//JS获取聊天未读信息总条数

            {

                [self.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"%@(%zi, 'ios')", callback, self.currentMessageCount]];

            }

            else if ([type isEqualToString:@"loginOut"])//用户退出登录

            {

                [self closeWebSocket];//断开websocket连接

                //把本地保存的用户名密码 注销掉  即密码清空

                [UserTool registerCurrentUser];

            }

            else if ([type isEqualToString:@"messageCountSubOne"])//用户聊天条数减一

            {

                self.currentMessageCount--;

            }

            return NO;

        }

        return YES;

    }

    2.OC调用JS的方法

    这个比较简单  只需JS定义一个全局的function函数  OC直接就可以调用  比如

    [webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"%@(%@, 'ios')", callback, jsonStr]];

    这个方法就是调用JS的callback函数   并且该函数有两个参数 分别是jsonStr  和  'ios'

    3.OC拦截JS的Alert 和 Confirm

    只需在OC里面新建一个UIWebView的分类,定义两个方法分别是

    /**

     *  拦截UIWebView中网页弹出的alert提示框

     *

     *  @param sender  UIWebView

     *  @param message 提示信息

     */

    - (void)webView:(UIWebView *)sender runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(CGRect)frame;

     

    /**

     *  拦截UIWebView中网页弹出的confirm提示框

     *

     *  @param sender  UIWebView

     *  @param message 提示信息

     */

    - (BOOL)webView:(UIWebView *)sender runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(CGRect)frame;

    并且实现  代码如下

    static BOOL diagStat = NO;

     

    - (void)webView:(UIWebView *)sender runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(CGRect)frame {

        

        UIAlertView* customAlert = [[UIAlertView alloc] initWithTitle:@"提示"

                                                              message:message

                                                             delegate:self

                                                    cancelButtonTitle:@"确定"

                                                    otherButtonTitles:nil];

        [customAlert show];

    }

     

    - (BOOL)webView:(UIWebView *)sender runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(CGRect)frame

    {

        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"提示"

                                                            message:message

                                                           delegate:self

                                                  cancelButtonTitle:@"取消"

                                                  otherButtonTitles:@"确定", nil];

        [alertView show];

        

        while (alertView.hidden == NO && alertView.superview != nil) {

            [[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01f]];

        }

        

        

        return diagStat;

    }

     

    -(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{

        if (buttonIndex==0) {

            diagStat=YES;

        }else if(buttonIndex==1){

            diagStat=NO;

        }

    }

    创建好这个分类之后  然后在你加载UIWebView的UIVIewCotroller中导入这个分类即可  会自动拦截JS的alert和Confirm   实现我们OC自己的方法   这个通常用来替换JS的alert提示框

     

    4.取消UIWebView加载的网页   长按会弹出提示框 为了使其更像原生态  可以禁止掉 代码如下

    #pragma mark 取消webView长按弹出copy菜单

    - (void)cancelWebViewPopCopyMenu

    {

        self.webView.dataDetectorTypes = UIDataDetectorTypeNone;

        [self.webView stringByEvaluatingJavaScriptFromString:@"document.body.style.webkitTouchCallout='none';"];

        [self.webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitUserSelect='none';"];

    }

  • 相关阅读:
    《JavaScript 源码分析》之 jquery.unobtrusive-ajax.js
    《JavaScript高级程序设计》读书笔记 2
    《JS设计模式笔记》构造函数和工厂模式创建对象
    《ES6基础教程》之 map、forEach、filter indexOf 用法
    《JS设计模式笔记》 5,适配器模式
    51Nod 1058 N的阶乘的长度
    ACM总结——2017区域赛网络赛总结
    ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛 题目9 : Minimum
    hiho一下 第168周
    Fast Matrix Calculation HDU
  • 原文地址:https://www.cnblogs.com/bing-ge/p/4815602.html
Copyright © 2011-2022 走看看