前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >来了,iOS的JSCore与H5的交互

来了,iOS的JSCore与H5的交互

作者头像
大话swift
发布2019-12-18 10:50:38
1.2K0
发布2019-12-18 10:50:38
举报
文章被收录于专栏:大话swift大话swift

h5概念很热,咱们不多多说,但是在移动端的App中某些需要快速开发的地方也是很有好处--可以把一部分不想做的,不方便做的甩给web端去做,咱么只需要做好native与web的通信就好啦?

今天的主角就是JSCore这个哥们,苹果爸爸开放出来很久被大家忽略的角色。这是一个很方便的进行JS与WebView进行通信的神器。既然是神器就理所当然能够方便的进行两端的相互通信。

在开始之前我们先来一个简单相互通信实例(大图)

1 native主动与WebView通信

2 webview调用native

在说通信之前我们先需要搞明白一个东西:WebView调用Native,native调用WebView肯定是相互知道对方的存在保存了对方的instance才行。我们先看一官方的文档

那么这个context我们怎么获取到呢?

代码语言:javascript
复制
[webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];

通过kvo我们可以从WebView中获取到,这个就是我们主动与js打招呼的桥梁。那么有了桥梁我们同样需要给WebView说一声让他知道native的存在---

self.ctx[@"App"] = self;

这样相互直接就知道对方的存,js通过App这个作为native的引用,native通过context进行发消息

1 native 主动发消息给WebView

上文我们拿到了js上下文,就可以直接调用js的function啦,例如我们传递网络中的token

代码语言:javascript
复制
    [self.ctx[@"getToken"] callWithArguments:@[[AppManager manager].token]];

2 js主动发送数据给native

这个过程稍微复杂点,需要通过Protocol来实现,可以拆分为两步:

① 声明通信接口

@protocol App <JSExport>

JSExportAs(popBack, -(void)popBack:(NSString *) action );

JSExportAs(look, -(void)lookGameDetail:(NSString *)spotid type:(NSInteger) type );

JSExportAs(refreshToken, -(void)refreshToken:(NSString *) action );

JSExportAs(pushToFishSpot, -(void)pushToFishSpot:(NSInteger) spotId );

@end

这里的JSExportAs是给我们的函数起了一个js调用的function起了个别名,进而兼容转换一线js的function与OC的函数的差异。

但是有一个点需要注意,我们暴露出的共js调用至少需要一个形参,也就是说,不传递数据也要有一个参数

② 传递给WebView的引用实现协议与函数

这里我们只看一个实现

-(void)popBack:(NSString *)action{

@weakify(self)

dispatch_async(dispatch_get_main_queue(), ^{

[weak_self.navigationController popViewControllerAnimated:YES];

});

}

这里有点需要注意:回来进行UI的操作请在主线程中操作

最后是一个兼容性的彩蛋,也是最坑的一点---alert

UIAlert在iOS 9之后慢慢被禁用,而到了iOS13之后这问题异常严重,然鹅直接js进行alert居然报错,好在是哟办法的

这里附上几种带和不带输入和提示框的webview的alert的处理方法

代码语言:javascript
复制
 self.ctx[@"window"][@"alert"] = ^(JSValue *message) {
                dispatch_async(dispatch_get_main_queue(), ^{
                //自定义原生提示框替换原来的提示框
        //           message.isString message.isBoolean
        //            [message toString]
        //            [message toBool]
                    
                     UIAlertController * alerVc = [UIAlertController alertControllerWithTitle:@"alert"
                                                                                     message: [message toString] preferredStyle:UIAlertControllerStyleActionSheet];
                    UIAlertAction * cancelAction = [UIAlertAction actionWithTitle:@"OK" style:0
                                                                          handler:^(UIAlertAction * _Nonnull action) {
                        
                    }];
                    [alerVc addAction:cancelAction];
                    
                    [self presentViewController:alerVc
                                       animated:YES
                                     completion:^{
                        
                    }];
                });
            };
            //解决confirm提示框显示异常问题
            self.ctx[@"window"][@"confirm"]=^(JSValue *message) {
                dispatch_async(dispatch_get_main_queue(), ^{
                  //自定义原生提示框替换原来的提示框
                    
                    
                               UIAlertController * alerVc = [UIAlertController alertControllerWithTitle:@"alert"
                                                                                                message: [message toString] preferredStyle:UIAlertControllerStyleActionSheet];
                               UIAlertAction * cancelAction = [UIAlertAction actionWithTitle:@"OK" style:0
                                                                                     handler:^(UIAlertAction * _Nonnull action) {
                                   
                               }];
                               [alerVc addAction:cancelAction];
                               
                               [self presentViewController:alerVc
                                                  animated:YES
                                                completion:^{
                                   
                               }];
                    
                });
            };
            //解决prompt提示框显示异常问题
            self.ctx[@"window"][@"prompt"] = ^(JSValue *message) {
                dispatch_async(dispatch_get_main_queue(), ^{
                  //自定义原生提示框替换原来的提示框
                    
                    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"alert" message:[message toString] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
                    [alert show];
                });
            };
 
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-12-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 大话swift 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档