JoyWKWeb组件分分钟带你实现H5与原生的交互

pod 'JoyWKWeb'

功能描述Demo地址:🦆

JoyWKWeb 是基于WKWebView封装的一个的快捷H5集成组件

设计目的:

1.解决繁琐的H5和原生的交互能力(只需要提注册自定义方法名集合即可实现)。
2.解决js交互和解耦合问题(只需扩展类实现方法,勿需关心js如何调用到原生方法,因为内部会通过H5调用时候的js然后通过反射找到扩展类方法并执行)。
3.动态管理H5版本资源包、下载&解压&压缩(组件内置资源下载管理器、支持不同H5资源包可以配置到不同的服务器动态)。
4.内置tabbar,可以通过服务器配置文件动态配置Tabbar上的Native/H5资源(远程&本地)。

主要功能:

1.快速的js注入方法,便于H5和OC进行交互、不需要实现WKWebView的代理

2.二级页面自动带导航返回、关闭、刷新功能、回退到一级页面后自动隐藏

3.页面悬浮关闭按钮(可自定义按钮图片和图片颜色)

4.通过category可以扩展和H5交互的方法、只需要两步1.实现注册的js方法2.通过WebVC暴露的方法注册js函数
即可(不需要通过wkwebview的代理去判断message name和body,WebVC已做了方法的反射)

5.支持OC回调H5,提供了转换H5可执行的js转换方法,只需要传入methodName和parameter即可转换成H5可识
别的标准json串.

6.支持远程url、本地H5资源、远程H5的压缩包资源(自动解压加载)

7.提供远程下载H5资源包的功能、以及资源包自动解压加载功能

8.提供远程配置文件下载缓存功能,可以远程配置总/子资源包下载地址、资源包版本、本地加载时会根据版本判断是否需
要下载新资源包还是直接使用缓存资源包

9.支持远程配置App的TabBar的各个模块、模块名、模块图片、可以远程压缩包、本地H5资源、远程H5地址、OC
原生ViewController的混合加载(如本地tabbar4个tab、tab1:远程url tab2:远程下载的压缩包中的vue编译
H5资源、tab3:本地项目中的html资源 tab4:原生控制器PersonalInfoViewController)

10.支持HTTP、HTTPS、url重定向功能(如:设置过滤http://www.joy.com后,可以重定向此域名下访问的资源
到本地资源)

11.集成了一些可以被H5调用的基本的功能,如打电话、发短信、获取手机系统版本、缓存数据、获取缓存数据、
清理缓存、展示/隐藏tabbar、页面回退功能

JoyWKWeb结构

1.WebVC 主要功能类可独立使用

2.WebVC+JSNative.h 扩展WebVC的功能、提供一些常用的系统方法封装以及便于原生对象转换H5可执行json的函数,可独立使用

3.UrlRedirectionProtocol 基于NSURLProtocol、用于配制需要拦截的域名以及拦截后相应资源的重定向

4.ResourcePackageManager.h 资源配置管理器:下载url对应的app的配置文件(或手动配制configDict对象)、并根据配制文件下载对应版本的H5压缩包、H5资源包的解压

5.TabBarVC 可配置的Tabbar控制器,需要配合ResourcePackageManager资源管理器远程配制tabbar上的菜单以及各菜单对应的H5URL、缓存资源、原生页面等。

使用方法

WebVC使用(主功能,可独立使用,快捷实现H5与原生的js交互)

WebVC *vc; //WebVC 初始化类型 KURLTypeURL/KURLTypeCache
vc = [[WebVC alloc]initWithType:KURLTypeURL url:h5Path];     //加载远程url
vc = [[WebVC alloc]initWithType:KURLTypeCache url:htmlPath]; //加载缓存地址
[vc addJsCallNativeMethods:[NSSet setWithArray:@[@"jsGetUserInfo",@"jsGetToken",@"jsSystemVersion",@"jsCallPhone"]]]; //注册和H5协定的js函数
[vc setCloseBtnColor:[UIColor orangeColor] image:nil];   //设置悬浮关闭按钮图片及图片的颜色
[self.navigationController pushViewController:vc animated:true];

实现注册的js方法

可以基于WebVC自建category实现私有方法,此外不再需要做其他步骤

extern const BOOL JS_Call_Method_IsBuild;
@interface WebVC (JSNative)
@end
@implementation WebVC (JSNative)
#pragma 打电话
- (void)jsCallPhone:(NSString *)phone{
    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"tel:%@",phone]];
    [self.wkWebView loadRequest:[NSURLRequest requestWithURL:url]];
}

#pragma 获取手机系统版本
- (void)jsSystemVersion:(id)obj{
    NSString* phoneVersion = [[UIDevice currentDevice] systemVersion];
    NSDictionary *jsDict = @{
        @"status":@"0",
        @"description":@"手机系统版本",
        @"body":@{
                @"value":phoneVersion}
    };

    //methodName:jsSystemVersion为H5中监听的js函数
    NSString *JSResult = JS_Call_Method_IsBuild?[self transferToJsBridgeJSonWithObject:jsDict methodName:@"jsSystemVersion"]:[NSString stringWithFormat:@"jsSystemVersionResult('%@')",phoneVersion];
    [self.wkWebView evaluateJavaScript:JSResult completionHandler:^(id _Nullable result, NSError * _Nullable error) {
        NSLog(@"%@", error);
    }];
}

H5中的js函数

//唤起电话
function jsCallPhone(){
    //android
    if  (checkIsAndroidType()){
        window.MainJsInterface.jsCallPhone("18666666666");
    }else {
    //ios
        window.webkit.messageHandlers.jsCallPhone.postMessage("18666666666");
    }
}

//获取系统版本
function jsSystemVersion(){
    if(checkIsAndroidType()){
        window.MainJsInterface.jsSystemVersion();
    }else {
        window.webkit.messageHandlers.jsSystemVersion.postMessage(null);
    }
}

//监听原生获取系统版本回调函数
document.addEventListener("jsSystemVersion", function(evt) {
    var content = "系统版本" + evt.detail["body"]["value"];
    alert(content);
});

//检查app系统
function checkIsAndroidType(){
    var u = navigator.userAgent;
    var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //android终端
    var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
    if    (isAndroid == true){
        return true
    }else if(isiOS == true){
        return false
    }
}

至此,你的App已经可以正常和H5通讯了,以下再讲一些扩展功能

ResourcePackageManager

//url:配置文件下载地址 success:成功回调 failure:失败回调,配置文件下载成功后会自动根据配置文件下载配置文件中对应的远程资源文件包并解压
-(void)downLoadConfig:(NSString*)url Success:(VOIDBLOCK)success failure:(ERRORBLOCK)failure;
//也可以自行通过category的方式扩展ResourcePackageManager 实现自己公司特殊的配置文件下载,比如token信息

TabBarVC

//结合ResourcePackageManager使用,tabbar会自动读取ResourcePackageManager配置文件并根据配置文件配置配置各tabbarItem上的Item

UrlRedirectionProtocol、UrlFiltManager

@interface UrlRedirectionProtocol : NSURLProtocol
//获取缓存路径
+(NSString *)getCachePath;
@end
@interface UrlFiltManager : NSObject
+ (instancetype)shareInstance;
@property (nonatomic,readonly)NSMutableSet *urlFiltSet;
//配置拦截的域名或地址
- (void)configUrlFilt:(NSArray *)urlFitArray;
@end

配置文件讲解

//配置文件可放到远程服务器下载或者赋值给ResourcePackageManager管理类的configDict

{
    "packageVersion": {
        "zipResource": "0",//模块名及版本号(type为zip类型的压缩包需要,其他本地资源、远程url、原生模块不需要配置)   
        "zip0":"0",
        "dist":"0",
        },
    "items":[//模块列表
        {
            "url": "http://127.0.0.1:8000/dist.zip",//压缩包下载地址
            "h5Path": "dist/index.html",//压缩包内资源文件
            "icon": "guanbi",//需要配置的tabbar上的icon名称
            "title": "vue",//tabbar模块名称
            "module":"dist",//模块名(用于查找对比版本)
            "version":"2",//远端资源包版本 
            "type": "zip"//模块类型zip:压缩包 resource:本地资源 remote:远程url native:原生模块
        },
        {
            "url": "http://127.0.0.1:8000/home.zip",
            "h5Path": "home/home.html",
            "icon": "guanbi",
            "title": "zip资源",
            "module":"zip0",
            "version":"2",
            "type": "zip"
        },
        {
            "url": "http://127.0.0.1:8000/zipResource.zip",
            "h5Path": "zipResource/zipResource.html",
            "icon": "guanbi",
            "title": "zip资源",
            "module":"zipResource",
            "version":"2",
            "type": "zip"
    },
        {
            "h5Path": "http://127.0.0.1:8000/flutter/flutter.html",
            "icon": "guanbi",
            "title": "远程资源",
            "type": "remote"
    },
        
        {
            "h5Path": "http://www.cocoachina.com",
            "icon": "guanbi",
            "title": "cocoachina",
            "module":"NativeVC",
            "version":"0",
            "type": "native"
    }]
}

简单的文件测试服务器

mac系统自带python环境
1.可创建一个文件夹,将配置文件和资源文件(压缩包和H5项目放置其中)
2.通过终端cd到文件夹目录
3.执行python -m SimpleHTTPServer 即可启动一个简易服务器(本地地址为http://127.0.0.1:8000),
如果安装的python版本为python3的话可以使用python3 -m http.server 8000启动服务
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容