iOS之WKWebView、UIWebView、WebViewJavascriptBridge三方框架

目录
    1. WKWebView
    2. UIWebView(javascriptcore.framework)
    3. 三方WebViewJavascriptBridge框架
1. WKWebView
:UIView  

  iOS8后推出
  Safari浏览器(iPhone、mac)都是基于WKWebView 实现的。
  相比WebView更省内存。

1.1 使用详解

#import     

    
/**
 初始化UI
 */
-(void)setupUI{
    [self.view addSubview:self.webView];
}
/**
 设置URL,并加载
 */
-(void)setUrlStr:(NSString *)urlStr{
    _urlStr=urlStr;
    
    [self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:urlStr]]];
}


-(WKWebView *)webView{
    if(!_webView){
        // 创建WKWebView
        _webView=[[WKWebView alloc]initWithFrame:CGRectZero configuration:({
            // 创建配置类
            WKWebViewConfiguration *config=[WKWebViewConfiguration new];
            config;
        })];
        [_webView setFrame:CGRectMake(0, C_NavBarAndStatusBarHeight, C_ScreenWidth, C_ScreenHeight-C_NavBarAndStatusBarHeight)];
        // 设置dele 
        [_webView setUIDelegate:self];
        [_webView setNavigationDelegate:self];
        
        // 设置其他
        [_webView setBackgroundColor:[UIColor whiteColor]];
        [_webView.scrollView setShowsVerticalScrollIndicator:false];
        [_webView.scrollView setShowsHorizontalScrollIndicator:false];
    }
    return _webView;
}

常用属性/方法

获取常用信息

    // 标题(readOnly)
    NSString *title=webView.title;
    // url地址(readOnly)
    NSURL *URL=webView.URL;  
    // 是否正在加载(readOnly)
    BOOL loading=webView.isLoading 
    // 加载进度(readOnly)
    double estimatedProgress=webView.estimatedProgress;  
    // 是否加密(readOnly)
    BOOL hasOnlySecureContent=webView.hasOnlySecureContent; 
    // scrollView(readOnly)
    UIScrollView *scrollView=webView.scrollView;
加载请求

    // loadRequest
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"url"]]];
    // 加载fileURL
    [webView loadFileURL:[NSURL URLWithString:@""] allowingReadAccessToURL:[NSURL URLWithString:@""]];
    // 加载data
    [webView loadData:[NSData data] MIMEType:@"" characterEncodingName:@"" baseURL:[NSURL URLWithString:@""]];
    // 加载本地html
    NSString *urlStr=[[NSBundle mainBundle]pathForResource:@"index.html" ofType:nil];
    [webView loadHTMLString:[NSString stringWithContentsOfFile:urlStr encoding:NSUTF8StringEncoding error:nil] baseURL:[NSURL URLWithString:urlStr]];
重新加载
    // 重新加载
    [webView reload];
    // 重新加载初始网址
    [webView reloadFromOrigin];
    // 停止加载
    [webView stopLoading];

预览
    // 设置 是否允许预览链接(默认:true)
    [webView setAllowsLinkPreview:true];
向前向后

    // 设置 是否支持手势前进后退(默认:false)
    [webView setAllowsBackForwardNavigationGestures:true];

    // 是否允许向后(readOnly)
    BOOL canGoBack=webView.canGoBack;
    // 是否允许向前(readOnly)
    BOOL canGoForward=webView.canGoForward;
    // 向后
    [webView goBack];
    // 向前
    [webView goForward];

    // 获取页面前进后退列表(readOnly)
    WKBackForwardList *list=webView.backForwardList;
    // 当前(readOnly)
    WKBackForwardListItem *item=list.currentItem;
    // 前一个(readOnly)
    WKBackForwardListItem *itemForward=list.forwardItem;
    // 后一个(readOnly)
    WKBackForwardListItem *itemBack=list.backItem;
    // 后列表(readOnly)
    NSArray *backList=list.backList;
    // 前列表(readOnly)
    NSArray *forwardList=list.forwardList;

    // 根据下标获取指定页
    WKBackForwardListItem *item=[list itemAtIndex:0];
    // 前进或后退到指定页
    [webView goToBackForwardListItem:item];

    // (readOnly)
    NSURL *URL=item.URL;
    NSURL *initialURL=item.initialURL;
    NSString *title=item.title;

dele

【OC调用js中的方法】
  [webView evaluateJavaScript:@"helloWorld" completionHandler:^(id _Nullable obj, NSError * _Nullable error) {}];


【js调用OC中的方法】
-(void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    // 首先设置交互(js调用OC),设置dele
    [self.webView.configuration.userContentController addScriptMessageHandler:self name:@"helloWorld"];
}
-(void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    // 最后移除交互
    [self.webView.configuration.userContentController removeAllUserScripts];
}

#pragma mark dele         
// js调用OC方法后调用(required)
-(void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
    NSLog(@"js调用OC方法后调用");
    SEL selector = NSSelectorFromString([NSString stringWithFormat:@"%@:",message.name]);
    if ([self respondsToSelector:selector]) {
        [self performSelector:selector withObject:message.body];
    }
}
// js中这样调用 window.webkit.messageHandlers.helloWorld.postMessage({body: 'hello world!'});
-(void)helloWorld:(NSDictionary *)dic{
    NSLog(@"");
}
#pragma mark dele    都为可选方法

// =============== alert、confirm、prompt

// js中调用alert后调用
-(void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{
    NSLog(@"js中调用alert");
    /*
     message:alert中的内容
     */
    completionHandler();
}
// js中调用confirm后调用
-(void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler{
    NSLog(@"js中调用confirm");
    /*
     message:confirm中的内容
     */
    // true确认,false取消
    completionHandler(true);
}
// js中调用prompt后调用
-(void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler{
    NSLog(@"js中调用prompt");
    /*
     prompt:标题
     defaultText:默认文本
     */
    // 文本框中的填写内容
    completionHandler(@"你好");
}


// =============== 预览

// 是否允许预览(长安链接时触发预览)
- (BOOL)webView:(WKWebView *)webView shouldPreviewElement:(WKPreviewElementInfo *)elementInfo{
    /*
     elementInfo.linkURL    预览的url
     */
    return true;
}
// 触发预览后调用,返回预览VC
- (nullable UIViewController *)webView:(WKWebView *)webView previewingViewControllerForElement:(WKPreviewElementInfo *)elementInfo defaultActions:(NSArray> *)previewActions{
    return [UIViewController new];
}
// 触发pop操作预览消失时调用
- (void)webView:(WKWebView *)webView commitPreviewingViewController:(UIViewController *)previewingViewController{
    NSLog(@"预览取消时调用");
}


// =============== 创建/关闭

// 创建新的webView后回调,调用window.open()创建新窗口后触发
-(WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures{
    
    // 必须使用configuration
    return [[WKWebView alloc]initWithFrame:CGRectZero configuration:configuration];
}
// 关闭当前webView后调用,调用window.close()触发
-(void)webViewDidClose:(WKWebView *)webView{
    NSLog(@"关闭webView");
}
#pragma mark dele      都为可选方法

// =============== 页面加载

// 页面开始加载时调用
-(void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{
    NSLog(@"页面开始加载");
}
// 开始加载内容后调用
-(void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation{
    NSLog(@"页面开始加载内容");
}
// 页面加载完成后调用
-(void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
    NSLog(@"页面加载完成");
}
// 页面加载失败后调用
-(void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error{
    NSLog(@"页面加载失败");
}
// 页面加载内容中断时调用
-(void)webViewWebContentProcessDidTerminate:(WKWebView *)webView{
    NSLog(@"加载内容中断");
}


// =============== 跳转

// 是否允许跳转(发送request请求之前调用)
-(void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{
    /*
     navigationAction.sourceFrame   原 WKFrameInfo(只读)
     navigationAction.targetFrame   目标 WKFrameInfo(只读)
     navigationAction.request       request(只读)
     navigationAction.navigationType    请求类型
        WKNavigationTypeLinkActivated,  // 链接href
        WKNavigationTypeFormSubmitted,  // 表单提交
        WKNavigationTypeBackForward,    // 返回
        WKNavigationTypeReload,         // 重新加载
        WKNavigationTypeFormResubmitted,// 表单重复提交
        WKNavigationTypeOther = -1,     // 其他
     
     WKNavigationActionPolicyAllow  允许
     WKNavigationActionPolicyCancel 拒绝
     */
    decisionHandler(WKNavigationActionPolicyAllow);
}
// 是否允许跳转(发送request请求并收到响应后)
-(void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{
    /*
     navigationResponse.forMainFrame    是否是main frame(只读)
     navigationResponse.response        获取响应response(只读)

     
     WKNavigationResponsePolicyAllow    允许
     WKNavigationResponsePolicyCancel   拒绝
     */
    decisionHandler(WKNavigationResponsePolicyAllow);
}
// 重定向后调用(接收到服务器的跳转请求)
-(void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation{
    NSLog(@"后端重定向");
}
// 跳转失败后调用
-(void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error{
    NSLog(@"跳转失败");
}
// https则调用
-(void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler{
    /*
     NSURLSessionAuthChallengeUseCredential,                    使用(信任)证书
     NSURLSessionAuthChallengePerformDefaultHandling,           默认,忽略
     NSURLSessionAuthChallengeCancelAuthenticationChallenge,    取消
     NSURLSessionAuthChallengeRejectProtectionSpace,            这次取消,下载次还来问
     */
    // challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust
    completionHandler(NSURLSessionAuthChallengeUseCredential,[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
}

1.2 其他

WKWebViewConfiguration

    // 1.创建配置类
    WKWebViewConfiguration *config=[WKWebViewConfiguration new];
    // 1.1设置偏好设置
    config.preferences=({
        WKPreferences *pre=[WKPreferences new];
        [pre setMinimumFontSize:10];                            // 最小字体(默认:0)
        [pre setJavaScriptEnabled:true];                        // js是否可用(默认:true)
        [pre setJavaScriptCanOpenWindowsAutomatically:false];   // js是否能通过打开窗口 (默认:false)
        pre;
    });
    // 1.2设置内容处理池
    config.processPool=[WKProcessPool new];
    // 1.3设置交互(js调用OC)
    [config setUserContentController:({
        WKUserContentController *userC=[WKUserContentController new];
        // 添加交互,当收到js调用ssbb后 回调didReceiveScriptMessage 
        [userC addScriptMessageHandler:self name:@"ssbb"];
        
        userC;
    })];
    
    // ---------- 其他常用属性 start 可选----------
    // 设置 持久化
    // 一个WKWebsiteDataStore对象代表了被网页使用的各种类型的数据。包括cookies,磁盘文件,内存缓存以及持久化数据如WebSQL,IndexedDB数据库,local storage。
    [config setWebsiteDataStore:[WKWebsiteDataStore defaultDataStore]];
    // 设置 在web全部加载到内存前是否阻止其显示
    [config setSuppressesIncrementalRendering:true];
    // 设置 UserAgent中的应用名称
    [config setApplicationNameForUserAgent:@""];
    // 设置 是否允许AirPlay播放媒体(默认:true)
    [config setAllowsInlineMediaPlayback:true];
    // 设置 是否忽略缩放属性(默认:false)覆盖网页中的user-scalable HTML属性
    [config setIgnoresViewportScaleLimits:true];
    // 设置 需要检测的数据类型(可对相应的类型做处理,如链接则可跳转)
    [config setDataDetectorTypes:WKDataDetectorTypeLink];
    /*
     WKDataDetectorTypeNone             不检测(默认)
     WKDataDetectorTypePhoneNumber      电话
     WKDataDetectorTypeLink             链接
     WKDataDetectorTypeAddress          地址
     WKDataDetectorTypeCalendarEvent    日历提醒事件
     WKDataDetectorTypeTrackingNumber   跟踪号码/查询号/运单号
     WKDataDetectorTypeFlightNumber     航班号
     WKDataDetectorTypeLookupSuggestion
     WKDataDetectorTypeAll              检测所有类型
     */
    // 设置 是否允许画中画播放?
    [config setAllowsPictureInPictureMediaPlayback:true];
    // 设置 选择内容的粒度级别
    [config setSelectionGranularity:WKSelectionGranularityDynamic];
    /*
     WKSelectionGranularityDynamic,     用户可自定义选择区域(默认)
     WKSelectionGranularityCharacter,   不可自定义选择区域
     */
    // 设置 是否使用在线的控制器(默认:false,使用本地的全屏控制器)
    [config setAllowsInlineMediaPlayback:true];
    // 设置 哪些视频需要用户手势才能自动播放
    [config setMediaTypesRequiringUserActionForPlayback:WKAudiovisualMediaTypeAll];
    /*
     WKAudiovisualMediaTypeNone     所有视频自动播放
     WKAudiovisualMediaTypeAudio    音频
     WKAudiovisualMediaTypeVideo    视频
     WKAudiovisualMediaTypeAll      所有都需要手势才能播放
     */
    //
    // ---------- 其他常用属性 end----------
2. UIWebView+原生框架(javascriptcore.framework)
  1. UIWebView 基础使用

UIWebView : UIView

    // 创建
    UIWebView *webV=[UIWebView new];
    [self.view addSubview:webV];

加载url  
    // 方式一:加载 url
    [webV loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@""]]];
    // 方式二:加载 htmlStr
    [webV loadHTMLString:@"

hello

" baseURL:nil]; // 方式三:加载 nsdata [webView loadData:[NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"1.docx" ofType:nil]] MIMEType:@"application/vnd.openxmlformats-officedocument.wordprocessingml.document" textEncodingName:@"UTF-8" baseURL:nil]; /* 1.docx application/vnd.openxmlformats-officedocument.wordprocessingml.document 2.pdf application/pdf 3.txt text/plain 4.html text/html */ 缓存 // 注意:缓存只影响本地址,页面内其他链接地址不受影响。 NSURLRequest *request=[[NSURLRequest requestWithURL:[NSURL URLWithString:@""] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10]]; /* NSURLRequestUseProtocolCachePolicy = 0, 默认(使用缓存) NSURLRequestReloadIgnoringLocalCacheData = 1, 忽略本地缓存 NSURLRequestReloadIgnoringLocalAndRemoteCacheData = 4, // Unimplemented NSURLRequestReloadIgnoringCacheData = NSURLRequestReloadIgnoringLocalCacheData, 忽略本地缓存 NSURLRequestReturnCacheDataElseLoad = 2, 返回缓存,缓存没有则请求网络 NSURLRequestReturnCacheDataDontLoad = 3, 返回缓存,缓存没有则出错 NSURLRequestReloadRevalidatingCacheData = 5, // Unimplemented */
dele
    // dele 
    [webV setDelegate:self];

/**
  * 是否允许该request请求进行加载(加载前调用)
  *
  *  1、调用loadRequest等会调用
  *  2、调用goBack后会调用(request的缓存策略是NSURLRequestReturnCacheDataElseLoad)
  *  3、页面内点击其他链接会调用(request的缓存策略是NSURLRequestUseProtocolCachePolicy)
  *  4、重定向会调用
  */
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{ 

  return true;
/*
    UIWebViewNavigationTypeLinkClicked,      用户触击了一个链接
    UIWebViewNavigationTypeFormSubmitted,    用户提交了一个表单
    UIWebViewNavigationTypeBackForward,      用户触击前进或返回按钮
    UIWebViewNavigationTypeReload,           用户触击重新加载的按钮
    UIWebViewNavigationTypeFormResubmitted,  用户重复提交表单
    UIWebViewNavigationTypeOther             发生其它行为
*/
}
// 开始加载(网页内容)后调用
- (void)webViewDidStartLoad:(UIWebView *)webView{}
// (网页内容完全显示在控件上)加载完毕后调用
- (void)webViewDidFinishLoad:(UIWebView *)webView{

    // 获取web页面内容信息
    NSString *docStr=[webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.textContent"];
    /*
     JavaScript的执行时间被限定在10秒钟,如果执行时间超过10秒,那么页面就停止执行这个脚本。
     JavaScript的执行可能阻塞主线程,所以当脚本执行的时候不允许用户影响页面的加载。
     JavaScript的内存分配被限制在10M,如果超出这个限制那么页面会发生异常。
     */
}
// 加载失败后调用
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{}
前进后退
    // 获取 页面数量
    NSInteger pageCount=webV.pageCount;
    // 是否 可以回退
    BOOL isCanBack=[webV canGoBack];
    // 是否 可以前进
    BOOL isCanForward=[webV canGoForward];
    // 回退
    [webV goBack];
    // 前进
    [webV goForward];

重新加载
    // 是否 正在加载
    BOOL isLoading=[webV isLoading];
    // 重新加载(会重新调用shouldStartLoadWithRequest等)
    [webV reload];
    // 停止加载
    [webV stopLoading];


滚动条
    // 设置 是否显示纵向滚动条
    [webV.scrollView setShowsVerticalScrollIndicator:true];
    // 设置 是否显示横向滚动条
    [webV.scrollView setShowsHorizontalScrollIndicator:true];

显示
    // 是否网页内容下载完毕才开始渲染web视图,默认为NO
    @property (nonatomic) BOOL suppressesIncrementalRendering;
    // 是否允许长按链接预览(支持3D Touch的设备),default is NO
    @property (nonatomic) BOOL allowsLinkPreview;

    // 设置是否缩放到适合屏幕大小(默认:false)
    [webV setScalesPageToFit:true];


其他
    // 设置 是否允许media后台播放
    [webV setAllowsInlineMediaPlayback:true];
    // 获取scrollView(只读)
    UIScrollView *scrollView=webView.scrollView;
    // 获取NSURLRequest (只读)
    NSURLRequest *request=webView.request;


    // 翻页效果(当网页的大小超出view时,将网页以翻页的效果展示)
    @property (nonatomic) UIWebPaginationMode paginationMode;
    /*
     UIWebPaginationModeUnpaginated,    // 不使用翻页效果
     UIWebPaginationModeLeftToRight,    // 将网页超出部分分页,从左向右进行翻页
     UIWebPaginationModeTopToBottom,    // 将网页超出部分分页,从上向下进行翻页
     UIWebPaginationModeBottomToTop,    // 将网页超出部分分页,从下向上进行翻页
     UIWebPaginationModeRightToLeft     // 将网页超出部分分页,从右向左进行翻页
     */
    // 分页模式
    @property (nonatomic) UIWebPaginationBreakingMode paginationBreakingMode;
    /*
     UIWebPaginationBreakingModePage,
     UIWebPaginationBreakingModeColumn
     */
    // 每一页的长度
    @property (nonatomic) CGFloat pageLength;
    // 每一页的间距
    @property (nonatomic) CGFloat gapBetweenPages;
    // 是否在弹出键盘后允许用户交互,默认YES
    @property (nonatomic) BOOL keyboardDisplayRequiresUserAction;

音视频
    // 是否允许分屏播放
    @property (nonatomic) BOOL allowsPictureInPictureMediaPlayback;
    // 是否使用内嵌HTML5播放视频(还是用本地的全屏控制)。
    // 内嵌则HTML中的video元素必须包含webkit-playsinline属性。
    // iPhone Safari defaults to NO. iPad Safari defaults to YES
    @property (nonatomic) BOOL allowsInlineMediaPlayback;
    // 是否允许自动播放,默认为YES
    @property (nonatomic) BOOL mediaPlaybackRequiresUserAction;
    // 音频播放是否支持air play功能,默认为YES
    @property (nonatomic) BOOL mediaPlaybackAllowsAirPlay;
  1. UIWebView 原生交互
    OC中可以直接调用JS方法
    JS可通过拦截url间接调用OC
    #import 
    


        // 创建UIWebView
        UIWebView *webV=[UIWebView new];
        [self.view addSubview:webV];
        // 布局,,,
        // 
        [webV setScalesPageToFit:true];
        // 滚动速度:正常速,默认慢速
        [webV.scrollView setDecelerationRate:UIScrollViewDecelerationRateNormal];
        // loadRequest(加载网页)
        [webV loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"url"]]];

dele

        // dele
        [webV setDelegate:self];

// 加载完成后调用
-(void)webViewDidFinishLoad:(UIWebView *)webView{

》》》》》OC调js
    // 初始化一些操作  (如:提交表单,插入内容,删除内容,修改内容,查询内容)
    [webView stringByEvaluatingJavaScriptFromString:@"js代码"];
    
举例:
    // 提交表单
    [webView stringByEvaluatingJavaScriptFromString:@"document.froms[0].submit();"];
    
    // 插入内容
    [webView stringByEvaluatingJavaScriptFromString:@" js 代码"];
    // 例:
    @"var script=document.createElement('script');"   // 可以是普通控件如img(.src .width .height)
    @"script.type='text/javascript';"
    @"script.text=\"function myFun(){"
    @"var f=document.getElementsByName(‘q’)[0];"
    @"f.value='11';"
    @"document.forms[0].submit();"
    @"}\";"
    @"document.getElementsByTagName('head')[0].appendChild(script);"
    
    // 删除内容
    [webView stringByEvaluatingJavaScriptFromString:@"document.getElementById('a').remove()"];
    
    // 修改内容值、显示值
    [webView stringByEvaluatingJavaScriptFromString:@"document.getElementsByName('a')[0].value='123'"];
    [webView stringByEvaluatingJavaScriptFromString:@"document.getElementsByName('a')[0].innerHTML='h123'"];
    
    // 查询内容
    // url
    NSString *urlStr=[webView stringByEvaluatingJavaScriptFromString:@"document.location.href"];
    // title : document.title


    // 禁用 页面元素选择
    [webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitUserSelect='none';"];    
    // 禁用 长按弹出ActionSheet
    [webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitTouchCallout='none';"];





》》》》》 js调用OC    (方式一,原生JavaScriptCore.framework框架(iOS7))
    #import  

    /* 2种方式:
        1、Block:暴露单个方法(不能直接使用JSValue、JSContext,造成循环引用)
        2、JSExport协议:暴露单个对象
     */

方式一(Block):
OC代码
     #import 
    // 获取 js代码的执行环境
    JSContext *context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    // Block (注册)
    context[@"js中的函数名"] = ^{
        NSArray *arg = [JSContext currentArguments];
    };
    context[@"js中的函数名"] = ^(NSDictionary *dic){
        NSLog(@"函数的实参值:%@", dic[@"color"]);
    };
js代码
    function testClick(){
        var str1=document.getElementById("text1").value;
        var str2=document.getElementById("text2").value;
        函数名(str1,str2);
    }
      
方式二():
    实现协议遵守,JS中调用时(会将方法转为驼峰式,也可以使用宏JSExportAs(sbAdd,+(void)method:(int)a with:(int)b))此宏只对带参有效
    JS中调用:对象.属性 , 对象.方法   (不能在这增加成员变量)
}



// 是否允许加载网络请求
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{

》》》》》 js调用OC    (方式二,拦截url)
    //
    NSString *urlStr=request.URL.absoluteString;
    //
    NSRange range=[urlStr rangeOfString:@"ssbb://"];
    if(range.location!=NSNotFound){
    
        NSString *method=[urlStr substringFromIndex:range.location+range.length];
        [self performSelector:NSSelectorFromString(method)];
        return false;
    }
    
    return true;
}
// 开始加载后调用
-(void)webViewDidStartLoad:(UIWebView *)webView{}
// 加载失败后调用
-(void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{}

注意事项

1.JS值的包装
        JS中的值拿到OC中是不能直接用的
        不能作为OC对象的属性

    JSValue *value=[context evalutateScript:@"2+2"];     [value toInt32];
    /*
     OC type            JS type
     
     nil                undefined
     NSNull             null
     NSString           string
     NSNumber           number,boolean
     NSDictionary       Object object
     NSArray            Array object
     NSDate             Date Object
     NSBlock            Function Object
     id                 Wrapper object
     Class              Constructor object
     */
3. WebViewJavascriptBridge框架(第三方框架)
    原理:拦截URL

         pod 'WebViewJavascriptBridge'
         #import "WebViewJavascriptBridge.h"
        // 基于WKWebView,则不用再设置WKWebView 的navigationDelegate(navDele为bridge)
        // 基于UIWebView,则不用再设置dele(dele为bridge)
        
        // 0.开启日志调试
        [WebViewJavascriptBridge enableLogging];
        // 1.创建WKWebView或UIWebView
        // 2.创建JavascriptBridge
        WebViewJavascriptBridge *_webViewBridge=[WebViewJavascriptBridge bridgeForWebView:webView];
        [_webViewBridge setWebViewDelegate:self];
        // 2.1配置
        // js调OC(注册多个handleName,用于js中调用)
        [_webViewBridge registerHandler:@"getUserIdFromOC" handler:^(id data, WVJBResponseCallback responseCallback) {
            // data
            // callBack
            if(responseCallback){
                responseCallback(@{@"userId":@"ssbb"});
            }
        }];
        // OC调js
        [_webViewBridge callHandler:@"getUserName" data:@{@"name":@"ssbb"} responseCallback:^(id responseData) {
            // responseData
        }];
~~~~~~~~JS


你可能感兴趣的:(iOS之WKWebView、UIWebView、WebViewJavascriptBridge三方框架)