美文网首页
在H5页面调用oc方法

在H5页面调用oc方法

作者: 溜溜leesin | 来源:发表于2018-12-13 17:15 被阅读74次

    背景---

    假设公司有一个比较复杂的页面需要我们来做,但是呢,如果使用原生来做呢,布局复杂做出来的东西也不好(也就是出力不讨好),那么我们就可以和我们的前端(爸爸~~)商量一下,让其帮忙做这个页面,然后点击页面的一些控件(按钮或者其他),我们自己做跳转到原生界面或者怎么样,这个过程呢,就是ios与原生的交互。

    今天只有一个例子,那就是如果在H5页面调用原生(iOS)的方法。通俗的说,就是页面人家前端给咱们做了,页面的点击事件或其他需要我们自己处理,我们怎么做~~~(部分代码参考一些前辈,如侵权请告知 删掉)

    首先,我对交互这块真的不懂,仅仅是把我自己学的分享一下,抛砖引玉。
    其次,建议用WKWebView,优势貌似比UIWebView多很多(google),而且今天在写代码发现UIWebView将要被废弃了,小伙伴们请周知~~(写的看着很多,其实就一点点内容)

    先看一部分代码

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>html5page-oc</title>
        <script>
            function btn1Click() {
                window.webkit.messageHandlers.NativeModel.postMessage({name: 'leeSin', age: 12});
                alert("after call");
            }
        </script>
    </head>
    <body>
    <input type="button" value="button c" onclick="btn1Click()">
    </body>
    </html>
    

    小伙伴看到上面的这些第一感觉是啥?WTF?我是这么感觉得...,没办法还是得硬着头皮看啊 心累------
    但我们仔细看看 里面有一个 function 这个和swift里面的func 有点类似,其实就是一个函数,这个函数名为btn1Click 有两个参数name age,另外看这句<input type="button" value="button c" onclick="btn1Click()"> 也就是这个是按钮的点击方法。知道了这个,我们就大体知道应该在我们的OC代码怎么处理这个点击方法了

    -(WKWebView *)webView
    {
        if (!_webView) {
            WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc]init];
            config.userContentController = [[WKUserContentController alloc]init];
            
            [config.userContentController addScriptMessageHandler:self name:@"NativeModel"];
            
            _webView = [[WKWebView alloc]initWithFrame:self.view.frame configuration:config];
            _webView.navigationDelegate = self;
        }
        return _webView;
    }
    

    上面是我们懒加载wkwebview的代码,这里的WKWebViewConfiguration 的文档说明:Using the WKWebViewConfiguration class, you can determine how soon a webpage is rendered, how media playback is handled, the granularity of items that the user can select, and many other options.
    WKWebViewConfiguration is only used when a web view is first initialized. You cannot use this class to change the web view's configuration after it has been created.
    也就是我们可以通过WKWebViewConfiguration配置网页的一些设置,比如网页的呈现时间,媒体播放的处理方式,用户可以选择的项目的粒度以及许多其他选项

    WKUserContentController 的说明: A WKUserContentController object provides a way for JavaScript to post messages and inject user scripts to a web view.
    翻译一下就是WKUserContentController对象为JavaScript提供了一种发布消息并将用户脚本注入Web视图的方法。

    通过设置 WKWebViewConfiguration 的 addScriptMessageHandler:name 来设置JS事件的接收处理器,这边设置为当前对象self,这里的name需要设置为JS中的调用的Model:NativeModel 。(这个NativeModel一定要和前段提供给我们的一致!!这个NativeModel一定要和前段提供给我们的一致!!这个NativeModel一定要和前段提供给我们的一致!!)
    
    /*! @abstract Adds a script message handler.
     @param scriptMessageHandler The message handler to add.
     @param name The name of the message handler.
     @discussion Adding a scriptMessageHandler adds a function
     window.webkit.messageHandlers.<name>.postMessage(<messageBody>) for all
     frames.
     */
    - (void)addScriptMessageHandler:(id <WKScriptMessageHandler>)scriptMessageHandler name:(NSString *)name;
    

    然后我们就可以在代理方法

    • (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message 处理啦~~~
    -(void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
    {
       // do what u want to do
        id body = message.body;
        NSLog(@"=====%@",body);
    }
    

    下面是文章的全部代码

    #import "ViewController.h"
    #import <JavaScriptCore/JavaScriptCore.h>
    #import <WebKit/WebKit.h>
    
    
    
    @interface ViewController ()<WKScriptMessageHandler,WKNavigationDelegate>
    
    @property (nonatomic,strong)WKWebView *webView;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
      [super viewDidLoad];
    
      NSURL *url = [[NSBundle mainBundle]URLForResource:@"jsDemo" withExtension:@"html"];
      NSURLRequest *requst = [NSURLRequest requestWithURL:url];
      [self.webView loadRequest:requst];
      
      [self.view addSubview:self.webView];
    }
    
    -(WKWebView *)webView
    {
      if (!_webView) {
          WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc]init];
          config.userContentController = [[WKUserContentController alloc]init];
          
          [config.userContentController addScriptMessageHandler:self name:@"NativeModel"];
          
          _webView = [[WKWebView alloc]initWithFrame:self.view.frame configuration:config];
          _webView.navigationDelegate = self;
      }
      return _webView;
    }
    
    #pragma marks -- delegate
    -(void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
    {
      id body = message.body;
      NSLog(@"=====%@",body);
    }
    
    @end
    
    - (void)viewWillDisappear:(BOOL)animated
    {
        [super viewWillDisappear:animated];    
        // 因此这里要记得移除handlers
        [self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"NativeModel"];
    }
    

    最后一定要把h5代码放到工程里呀 Command+N ---> Other-->Empty 赋值h5代码后 保存为XX.html 就ok啦

    总结起来就三点内容:
    1.前端和苹果移动端的方法名必须一致,且前端要以固定的格式来写方法,否则移动端收不到事件反馈;
    2.通过 WKUserContentController 添加html中预留的方法;
    3.实现 WKScriptMessageHandler 的代理方法;

    后记:1.后面应该还会继续写一下交互的文章,因为感觉自己还是不是很透彻,没关系的,每天进步一点点~相信积累的力量!2.感觉网络上的文章资料比较多,比较杂,其中优秀的文章很多,但是一些误导性的也存在 记住适合自己的就是好的~~ 加油!!!

    相关文章

      网友评论

          本文标题:在H5页面调用oc方法

          本文链接:https://www.haomeiwen.com/subject/jdjbhqtx.html