在H5页面调用oc方法

2018-12-13  本文已影响74人  溜溜leesin

背景---

假设公司有一个比较复杂的页面需要我们来做,但是呢,如果使用原生来做呢,布局复杂做出来的东西也不好(也就是出力不讨好),那么我们就可以和我们的前端(爸爸~~)商量一下,让其帮忙做这个页面,然后点击页面的一些控件(按钮或者其他),我们自己做跳转到原生界面或者怎么样,这个过程呢,就是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
{
   // 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.感觉网络上的文章资料比较多,比较杂,其中优秀的文章很多,但是一些误导性的也存在 记住适合自己的就是好的~~ 加油!!!

上一篇下一篇

猜你喜欢

热点阅读