金剛娃談UIWebView與JS交互

1.JS調用OC的方法   ios

OC自定義一個協議 例如YBHTTP:。JS遵循這個協議,發出一個請求window.location.href='YBHTTP:http://www.baidu.com'web

OC在json

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType 這個代理方法中攔截該請求  並根據以前規定好的協議解析這個請求,這樣就知道JS要OC作什麼事情,而後OC在作相應的事。相關代碼僅供參考websocket

#define kJSCallOCRequestDataHeader @"YBHTTP:" //js調用oc方法請求數據的協議頭socket

#define kJSCallOCWebSocketHeader @"websocket:" //js調用oc方法 websocket相關函數

先說明一下 kJSCallOCRequestDataHeader  kJSCallOCWebSocketHeader是定義好的宏   JSCallOCProtocol是我本身定義的一個模型  [JS_OC JSCallObjcWithJSCallOCProtocol:jsCallOCProtocol webView:webView]這個是我解析協議以後我OC要作的事oop

下面的代碼解析了兩個協議 lua

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

{spa

    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';"];

}

相關文章
相關標籤/搜索