精华内容
下载资源
问答
  • swift4 - wkwebview交互

    千次阅读 2017-12-22 10:43:38
    WKWebView用法介绍本文swift与WKWebView交互Demo地址前言:苹果在iOS8中推出了webkit新框架,提供了WKWebview组件用来替换存在各种问题的UIWebview,用WKWebview加载网页,相较于UIWebview速度更快了,内存占用更少了...

    WKWebView用法介绍

    本文swift与WKWebView交互Demo地址

    前言:苹果在iOS8中推出了webkit新框架,提供了WKWebview组件用来替换存在各种问题的UIWebview,用WKWebview加载网页,相较于UIWebview速度更快了,内存占用更少了。WKWebview还提供了更加丰富的接口,功能更加强大,刚学习swift4,代码撸了一个swift4版与WKWebView交互,特此分享出来,与大家共勉

    1.首先Xcode链接手机,运行项目工程,打开html界面,然后选中电脑上的safari的开发工具,打开html调试器。

    还不会电脑调试html?看这里

    使用safari对webview进行调试

    项目运行成功,打开我们的调试器如图

    6B74B7D4-42C1-4DF2-A3A8-B913BD3B81B4.png

    打开之后的界面

    image.png

    发现新大陆了,以后妈妈再也不用担心我的成长了。
    这里是以我的上线项目工程为例。大家可以看到上图中的交互,开出的get_selection_txt(),get_share_txt()等几个方法,这是我们苹果端需要调用执行的代码,细心的同学会看到方法内部做了一个判断。没错就是判断是android或者是苹果端的代码。我们暂且不讨论android,主要看下苹果端的这句代码
    window.webkit.messageHandlers.webViewApp.postMessage({get_selection_txt:rng_string});
    

    从字面上可以看出,是前端向移动端发送命令的语句,这里注意下webViewApp,这是一个交互关键。需要提前和前端人员商量好命名规则。我们两端都需要用到

    2.到这里,前端的看的就差不多了,我们来看下swift版本的实现方法

    image.png
    image.png

        private lazy var articleWeb : WKWebView = {
            let webView = WKWebView.init(frame: view.bounds, configuration: configutation)
            webView.allowsBackForwardNavigationGestures = true
            webView.navigationDelegate = self
            webView.uiDelegate = self
            webView.scrollView.delegate = self
            return webView
        }()
    
        private lazy var configutation: WKWebViewConfiguration = {
           let config = WKWebViewConfiguration()
            config.userContentController.addUserScript(String.userScript())
            config.userContentController.add(WeakScriptMessageDelegate.init(delegate: self), name: "webViewApp")
            return config
        }()
    
        private lazy var progressView : UIProgressView = {
            let pp = UIProgressView.init(frame: CGRect.init(x: 0, y: 64, width: view.frame.size.width, height: 2))
            pp.tintColor = UIColor.blue
            pp.backgroundColor = UIColor.lightGray
            pp.transform = CGAffineTransform.init(scaleX: 1, y: 1)
            return pp
        }()
    
        func Menu() -> Void {
            let menu = UIMenuController.shared
            let item = UIMenuItem.init(title: "划重点", action: #selector(point))
            let shareItem = UIMenuItem.init(title: "分享", action: #selector(share))
            let copyItem = UIMenuItem.init(title: "拷贝", action: #selector(copyAction))
    
            menu.menuItems = [item,shareItem,copyItem]
            menu.arrowDirection = .default
            menu.setTargetRect(articleWeb.bounds, in: articleWeb)
            menu.setMenuVisible(true, animated: true)
    
        }
    

    .上图中大家可以看到,用到了前端定义名称webViewApp,实现交互

    实现UIMenuController的点击方法,因为本文主要讲解交互,对于创建UIMenuController不做重点解析

    image.png

        @objc func point() {
            articleWeb.evaluateJavaScript("get_selection()", completionHandler: nil)
        }
    
        @objc func share() {
            articleWeb.evaluateJavaScript("get_selection_txt()", completionHandler: nil)
        }
    
        @objc func copyAction() {
            articleWeb.evaluateJavaScript("window.getSelection().toString()") { (object, error) in
                print(object!)
            }
        }
    
    

    .这里实现了点击方法,用到了上图中前端定义好的方法。get_selection_txt(),get_selection()

    3.细心的同学会发现,我有看到html往移动端发送数据啊。对。确实很多项目中很多情况下,都是我们调用前端方法,然后他们返回给我们数据我们再进行逻辑和处理。这里我们实现WKScriptMessageHandler这个代理方法,实现我们的需求。上代码

    image.png

    extension ArticleDetialViewController: WKScriptMessageHandler{
        func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
            print(message.body)
    
        }
    }
    

    有兴趣的同学,可以下载文章顶部的demo进行调试,打印print(message.body),里边的数据即是前端传递给我们的数据。是不是很简单呢

    。OC版的如果小伙伴们有需要可以私信或者下方评论我会尽快出一个oc版的wkwebview交互

    本文swift与WKWebView交互Demo地址

    献给所有和我一起奋斗在swift4学习路上的小伙伴

    展开全文
  • vue WKWebView 交互

    2020-07-09 21:06:40
    重新整理一下网页与原生的交互 iOS Objective-c 懒加载个webview @interface ViewController ()<WKScriptMessageHandler> @property(nonatomic,strong) WKWebView *webView; @end -(WKWebView *)webView{ ...

    写在开始

    目前AppStore提交已经彻底废弃UIWebView 以前一键接入的webjavascriptbridge也该放弃了
    重新整理一下网页与原生的交互

    iOS Objective-c

    懒加载个webview

    @interface ViewController ()<WKScriptMessageHandler>
    
    @property(nonatomic,strong) WKWebView *webView;
    
    @end
    
    -(WKWebView *)webView{
        if (!_webView) {
            // 创建一个配置类
            WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc]init];
            WKUserContentController *userContentController = [[WKUserContentController alloc]init];
            // 监听js调用 具体调用方式在js端
            // 需要实现WKScriptMessageHandler 中方法  在下文↓
            [userContentController addScriptMessageHandler:self name:@"jsCallNative"];
            configuration.userContentController = userContentController;
            _webView = [[WKWebView alloc] initWithFrame:self.view.bounds configuration:configuration];
            _webView.navigationDelegate = self;
            _webView.scrollView.bounces = NO;
            [_webView setBackgroundColor:[UIColor colorWithRed:0 green:0 blue:0 alpha:1]];
        }
        return _webView;
    }
    
    

    实现WKScriptMessageHandler userContentController 监听js调用

    - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
        // 登陆保存token
        if ([message.name isEqualToString:@"jsCallNative"]) {
            // data is message.body
        }
    }
    

    调用js中的方法

    [self.webView evaluateJavaScript:[NSString stringWithFormat: @"nativeCallJS(%@)" ,[params JSONString] ]completionHandler:^(id _Nullable result, NSError * _Nullable error) {
                    NSLog(@"调用js返回%@",result);
                }];
    
    

    js

    前端用的vue 大同小异

    监听原生的调用

    export default{
        ...
        created(){
            window.nativeCallJS = this.nativeCallJS
        },
        methods:{
            nativeCallJS:function(data){
                return "return data" + data
            }
        }
        ...
    }
    

    调用原生的方法

    window.webkit.messageHandlers.jsCallNative.postMessage(params)
    

    代码中无聊的地方太多 只是找些关键的贴出来 可能有错字 你说气不气

    展开全文
  • ios-JS wkWebView交互.zip

    2019-07-11 19:09:46
    js调用swift的方法打开相机相册,压缩图片然后通过参数传给js方法 网页显示压缩后的图片
  • js 与WKWebView 交互

    2019-03-25 07:39:24
    实现delegate WKUIDelegate,WKNavigationDelegate,WKScriptMessageHandler ...注入要和js交互的方法 WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init]; WKUserContentControll...

    实现delegate WKUIDelegate,WKNavigationDelegate,WKScriptMessageHandler

    js调起oc的方法

    注入要和js交互的方法

        WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
        WKUserContentController *userContentController = [[WKUserContentController alloc] init];
        [userContentController addScriptMessageHandler:self name:@"splitGotoWebPage"];
        [userContentController addScriptMessageHandler:self name:@"splitShareDialog"];
    复制代码

    设置代理

        _webView.UIDelegate = self;
        _webView.navigationDelegate = self;
    复制代码

    实现代理方法 (js 调起 oc)

    - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
        MALog(@"%@",message.name);
        MALog(@"%@",message.body);
        NSString *method = [NSString stringWithFormat:@"%@:",message.name];
        SEL selector = NSSelectorFromString(method);
    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
        if ([self respondsToSelector:selector]) {
            [self performSelector:selector withObject:message.body];
        }
    #pragma clang diagnostic pop
    }
    复制代码

    js 要如何做

    window.webkit.messageHandlers.<name>.postMessage(<messageBody>) for all
    复制代码
    • name 为[userContentController addScriptMessageHandler:self name:@"splitShareDialog"];中的name
    • postMessage(_nonull), 如果方法的返回参数为空 不能调起oc的方法

    oc 调起js

    声明方法

    //一个参数时
    NSString *jsStr = [NSString stringWithFormat:@"function(%@)",@"abc"]; 
    // 多个参数传递的是时候
    NSString *jsStr = [NSString stringWithFormat:@"function('%@','%@')",@"abc",@"123"]; 
    复制代码
    • 如何调用
    //oc 调用js
      [self.webView evaluateJavaScript:jsStr completionHandler:^(id _Nullable reponse, NSError * _Nullable error) {
            MALog(@"%@",error);
        }];
    复制代码
    • function 要和js的中的方法名是一致的
    • webview 如何禁止缩放
    //web页面进制缩放
        NSString *js = @" $('meta[name=description]').remove(); $('head').append( '<meta name=\"viewport\" content=\"width=device-width, initial-scale=1,user-scalable=no\">' );";
        WKUserScript *script = [[WKUserScript alloc] initWithSource:js injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:NO];
        [userContentController addUserScript:script];
    复制代码

    转载于:https://juejin.im/post/5c9881c4518825341467edbc

    展开全文
  • 前言 现在多数项目中会有使用webView的情况,过去往往使用UIWebView解决问题,但是由于其各种不便,给...WKWebView是继承自UIView的,因此构建方式还是很老套的,通常 - (instancetype)initWithFrame:(CGRect)fra...

    前言

    现在多数项目中会有使用webView的情况,过去往往使用UIWebView解决问题,但是由于其各种不便,给开发者带来了很多麻烦。现在项目中有所使用,所以写一篇总结,方便以后用到了查找和使用也为了方便其他同行。

    正文

    基础使用

    构建和配置

    WKWebView是继承自UIView的,因此构建方式还是很老套的,通常

    - (instancetype)initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration
    

    这个方法就够用了,第一个参数不多说,按照通常的使用就可以,第二个参数是对webView的配置对象,里面有很多属性可以使用,但是这里我只进行最简单使用的说明。

    WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc]init];
    configuration.preferences.minimumFontSize = 10;//设置最小字体
    configuration.preferences.javaScriptEnabled = YES;//是否可以使用JavaScript
    configuration.preferences.javaScriptCanOpenWindowsAutomatically = NO;//JS是否可以自动打开页面
    

    以上配置就足够正常使用,其他的如果项目还有需要,请自己根据需要添加。
    然后是对WKWebView的基本设置,

    self.webView.scrollView.bounces = NO;
    self.webView.navigationDelegate = self;
    

    设置了取消弹性和代理,需要说明的是由于我们使用的是需要和JS进行交互的webView,所以需要在ViewController中声明两个代理WKNavigationDelegate,WKScriptMessageHandler,前者是用来处理webView加载视图的各种情况的,后者是主要用来处理交互事件的。
    最后通过addSubView添加视图到父视图上面就可以了,这个时候应该是没有加载任何页面的webView。而主要功能加载web网页,需要使用以下方法:

    @property (nonatomic, strong) NSURLRequest *resetUrlRequest;
    
    self.resetUrlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:@"你所需要加载的网址"]];
    

    当然考虑项目中可能会对网址进行拼接,如拼接token,因此强烈建议,将后面的URL构建部分挪到顶上分出来写。

    基本代理相关

    常用的有:

    //开始加载
    -(void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation
    //加载完成
    -(void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
    //页面跳转失败
    - (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error
    //加载报错,通常来说如果页面出现不存在等问题,会走这里,如果需要对空白页面进行处理,在这里处理
    - (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error
    //请求之前,决定是否要跳转:用户点击网页上的链接,需要打开新页面时,将先调用这个方法。
    - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
        
        //允许页面跳转
    //    NSLog(@"%@=========tw============",navigationAction.request.URL);
        //如果是跳转一个新页面
        if (navigationAction.targetFrame == nil) {
            [webView loadRequest:navigationAction.request];
        }
        
        decisionHandler(WKNavigationActionPolicyAllow);
    }
    //接收到相应数据后,决定是否跳转
    - (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{
        
        if (((NSHTTPURLResponse *)navigationResponse.response).statusCode == 200) {
            decisionHandler (WKNavigationResponsePolicyAllow);
        }else {
            decisionHandler(WKNavigationResponsePolicyCancel);
        }
    }
    

    还有这些可能需要的

    // 主机地址被重定向时调用
    - (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(null_unspecified WKNavigation *)navigation;
    // 当内容开始返回时调用
    - (void)webView:(WKWebView *)webView didCommitNavigation:(null_unspecified WKNavigation *)navigation;
    // 如果需要证书验证,与使用AFN进行HTTPS证书验证是一样的
    - (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *__nullable credential))completionHandler;
    //9.0才能使用,web内容处理中断时会触发
    - (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView NS_AVAILABLE(10_11, 9_0);
    

    到此,基础的使用结束。

    限制用户选择以及长按操作

    有时候,我们会遇到一个比较头疼的问题,我们不想让用户长按选择或者有弹窗,那么这时我们需要添加两行代码来禁止这一系列行为。

    //WKWebview 禁止长按(超链接、图片、文本...)弹出效果
    [self.webView evaluateJavaScript:@"document.documentElement.style.webkitTouchCallout='none';" completionHandler:nil];
    [self.webView evaluateJavaScript:@"document.documentElement.style.webkitUserSelect='none';" completionHandler:nil];
    

    值得注意的是,这里其实是通过调用webView直接使用JS代码实现的操作,如果有需要还可以实现别的功能,而且这个方法最后有一个执行完毕之后的block,可以实现很多操作。

    添加进度条

    构建

    @property (nonatomic, strong)UIProgressView *progressView;
    
    //添加进度条
    self.progressView = [[UIProgressView alloc]initWithFrame:CGRectMake(0, 2, self.view.frame.size.width, self.view.frame.size.height)];
    self.progressView.tintColor = UIColorWithRGB(254, 79, 109);
    [self.webView addSubview:self.progressView];
    [self.webView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];
    

    监听

    #pragma mark - 进度条
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
        
        if ([keyPath isEqual:@"estimatedProgress"] && object == self.webView) {
            [self.progressView setAlpha:1.0f];
            [self.progressView setProgress:self.webView.estimatedProgress animated:YES];
            if (self.webView.estimatedProgress  >= 1.0f) {
                [UIView animateWithDuration:0.3 delay:0.3 options:UIViewAnimationOptionCurveEaseOut animations:^{
                    [self.progressView setAlpha:0.0f];
                } completion:^(BOOL finished) {
                    [self.progressView setProgress:0.0f animated:YES];
                    self.progressView.hidden = YES;
                }];
            }
        }else{
            [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
        }
    }
    

    代理中操作

    -(void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{
        
        self.progressView.hidden = NO;
        self.progressView.transform = CGAffineTransformMakeScale(1.0, 1.5);
        [self.view bringSubviewToFront:self.progressView]; // 将progress放到最前面
    }
    
    -(void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
        self.progressView.hidden = YES;
        self.title = self.webView.title;
        
        //WKWebview 禁止长按(超链接、图片、文本...)弹出效果
        [self.webView evaluateJavaScript:@"document.documentElement.style.webkitTouchCallout='none';" completionHandler:nil]; 
        //    [self.webView evaluateJavaScript:@"document.documentElement.style.webkitUserSelect='none';" completionHandler:nil];
        
    }
    - (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error{
        NSLog(@"%@---------------",error);
        self.progressView.hidden = YES;
        
    }
    - (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error{
        NSLog(@"%@-------------------",error);
        //加载本地的一个空页面的操作
        //[self sk_loadErrorPage];
    }
    

    返回上级以及popViewController

    	if ([[self.webView.backForwardList currentItem].title isEqualToString:@"首页"]) {
            [self.navigationController popViewControllerAnimated:YES];
        }
        if ([self.webView canGoBack]) {
            //控制订单列表中的较多界面折回
            if ([[self.webView.backForwardList currentItem].title isEqualToString:@"订单列表"] &&
                [[self.webView.backForwardList backItem].title isEqualToString:@"订单列表"]) {
                [self.webView goToBackForwardListItem:[self.webView.backForwardList backList].firstObject];
            }else{
                [self.webView goBack];
            }
            
        }else{
            [self.navigationController popViewControllerAnimated:YES];
        }
    

    可以对H5页面的标题进行判断来决定是否跳转。

    重点:JS交互

    WKWebView的交互方法和之前的UIWebView其实本质上没有什么太大的差别,都是通过发送方法名找到对应的方法执行对应的操作。我的具体操作如下:

    -(void)viewWillAppear:(BOOL)animated{
        //    self.navigationController.navigationBar.hidden = NO;
        if (self.webView) {
            if (self.webView.configuration.userContentController.userScripts.count>0) {
                //移除所有的监听
                [self removeAllScriptMsgHandle];
            }
            //对JS调用的方法进行监听,最好集中处理
            [self.webView.configuration.userContentController addScriptMessageHandler:self name:@"mjxLogin"];
        }
    }
    -(void)viewWillDisappear:(BOOL)animated{
        [self removeAllScriptMsgHandle];
    }
    - (void)dealloc{
    	//移除监听和代理
        [self.webView removeObserver:self forKeyPath:@"estimatedProgress"];
        [self.webView setNavigationDelegate:nil];
        [self.webView setUIDelegate:nil];
    }
    -(void)removeAllScriptMsgHandle{
        
        //移除监听,不移除一定会报错
        [self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"mjxLogin"];
       
    }
    
    

    对监听的处理的代理

    //用来接收js调用本地方法的拦截器
    -(void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
    //    NSLog(@"%@------mes------",message.body);
        //分享,多参数的情况
        if ([message.name isEqualToString:@"mjxShare"]) {
            NSDictionary *messageDic = message.body;
            [self shareGoodsWithTitle:messageDic[@"title"] withContent:messageDic[@"content"] withUrl:messageDic[@"url"] withImage:messageDic[@"img"]];
        }
        //申请试用,带一个参数的情况
        if ([message.name isEqualToString:@"mjxApply"]) {
            NSDictionary *messageDic = message.body;
            [self requestApplyGoods:messageDic[@"trade_sn"]];
            
        }
        //弹出错误信息
        if ([message.name isEqualToString:@"errorAlert"]) {
            [SKHUD showErrorWithStatus:message.body];
        }
      
        //保存二维码
        if ([message.name isEqualToString:@"codeImg"]) {
            [SVProgressHUD show];
            NSDictionary *messageDic = message.body;
            
            NSURL *url = [NSURL URLWithString:messageDic[@"codeImgUrl"]];
            
            NSData *data = [NSData dataWithContentsOfURL:url];
            UIImage *img;
            img = [UIImage imageWithData:data];
            
            
            UIImageWriteToSavedPhotosAlbum( img, self,@selector(imageSavedToPhotosAlbum:didFinishSavingWithError:contextInfo:) , NULL);
        }
        
    }
    

    到此,相关使用全部结束,希望喜欢活有用的话,能够点赞或者评论支持,谢谢。

    展开全文
  • 这是一个简化 WkWebview 和 Web 前端交互通信的框架 安装 你可以通过 pod 安装 pod 'WkBridgeSwift' 或者你可以直接使用源码 使用 导入模块: import WkBridgeSwift 假设你项目中已经存在 wkwebview 实例,那么直接...
  • js与oc原生WKWebView交互传值

    千次阅读 2018-08-15 17:29:31
    最近在做移动端实现H5支付,需要与JS交互,实现状态提醒,...先看下四中交互方式:(我用的第三种,现在都是在用wkwebview不建议用webview) 1.拦截网址(适用于UIWebView和WKWebView) 2.JavaScriptCore(只适用...
  • iOS JavaScriptCore 和 WKWebView交互

    千次阅读 2017-03-23 10:56:07
    基于wkwebview的和JS 交互 遵守两个协议 < WKNavigationDelegate,WKScriptMessageHandler > WKWebViewConfiguration * configuration = [[ WKWebViewConfiguration alloc]init]; ...
  • 虽然中途也一直寻思着升级到WKWebView,但奈何项目中业务众多又是分布式的,和js交互的地方也很多,而WKWebView和UIWebView的交互方法写法又不一样,前端得区分是Android还是iOS,所有有交互的地
  • ios与H5通过WKWebView交互详解

    千次阅读 2018-05-25 18:15:34
    WK的基本用法先不说了,主要在这里记录一下使用WKWebView在于H5交互时走过的一些坑,以及如果web端的同学如果没有做过和ios端的交互,那么自己也可以去帮助web端去完成;另外在调试过程中,也不用一味的去等待和H5去联调,...
  • mPaaS使用的就是系统提供的最原始的交互方式,包括 WKWebView调用原生 和 原生调用WKWebView WKWebView调用原生 调用原生就找这个方法- (void)userContentController:(WKUserContentController *)...
  • 以下简单列出WKWebView的使用及注意事项. 初始化webview及事件监听 fileprivate lazy var webView: WKWebView = { let webConfiguration = WKWebViewConfiguration() webConfiguration.preferences = WKP...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,761
精华内容 1,104
关键字:

wkwebview交互