18年元旦三天内和朋友突击了下,勉强是将雏形作出来了,后续的API慢慢完善。(固然了,主力仍是那个朋友,本人只是初涉iOS,勉强能看懂,修修改改而已)前端
大体内容以下:ios
JSBridge核心交互部分git
ui
、page
等部分经常使用API的实现(其它慢慢完善)github
组件(自定义)API拓展的实现web
API的权限校验仅预留了一个入口,模拟最简单的实现api
其它如离线资源加载更新,底层优化等机制暂时不提供架构
这个项目中,为了方便,就没有分红多个静态库了(事实上是能够这样作的),而是所有都放在一个项目中app
总体目录结构以下:框架
quickhybrid-ios |- AppDelegate // 应用入口,分发进入对应的viewcontroller |- core // 核心工具类,放一些通用工具类 | |- ui | |- util | |- ... |- quickhybrid // JSBridge实现的核心代码,定制viewcontroller,实现API等 | |- WebViewJavascriptBridge | |- basecore | |- quickcore | |- api
和Android同样,仍然是简单的三次架构:底层核心工具类->JSBridge桥接实现->app应用实现
工具
其中,core和jsbridge有必要的话能够打包成静态库
core |- ui // 一些UI效果的定义与实现 |- util // 通用工具类 quickhybird |- WebViewJavascriptBridge // 第三方开源的jsbridge实现,里面进行了修改 |- basecore // 定义基类viewcontroller |- quickcore // 定义quickhybrid中的viewcontroller实现 |- api // 定义API,开放原生功能给H5 应用内 |- AppDelegate // 应用入口,分发进入对应的viewcontroller |- MainViewController // 入口界面 |- TestPayApi // 定义的一个测试支付组件(自定义)API |- qhjsmodules.plist // 内部定义模块的别名于路径关系的配置文件
iOS能够直接在info.plist中配置权限,譬如
<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> </dict> <key>NSCameraUsageDescription</key> <string>是否容许应用使用摄像头?</string> <key>NSLocationWhenInUseUsageDescription</key> <string>是否容许应用使用定位功能</string> <key>NSMicrophoneUsageDescription</key> <string>是否容许应用使用麦克风?</string> <key>NSPhotoLibraryUsageDescription</key> <string>是否容许访问相册</string> <key>UIFileSharingEnabled</key> ...
Bundle Identifier: com.quickhybrid.quickhybriddemo Version: 1.0.0 Deployment Target: 11.2(默认最新调试) Devices: Universal Signing: none
相比Android中一堆复杂的配置,iOS中无疑简单不少,直接用最新系统调试便可。。。
这里,到目前位置,这个项目还有不少API没有实现,后续预计是会引入部分静态库的。
固然,若是想要引入静态库,也很简单,直接以下:
项目配置->Build Phases->Link Binary With Libraries->+(添加)->而后须要用到的地方import便可
整个过程很是的轻松愉快。
代码方面,也没法一一所有说明,这里仅列举一些比较重要的步骤实现,其他可参考源码
前面的JS项目中就已经有提到UA约定,就是在加载对于webview时,统一在webview中加上以下UA标识
// 获取默认UA NSString *defaultUA = [[UIWebView new] stringByEvaluatingJavaScriptFromString:@"navigator.userAgent"]; NSString *version = @"1.0.0"; NSString *customerUA = [defaultUA stringByAppendingString:[NSString stringWithFormat:@" QuickHybridJs/%@", version]]; [[NSUserDefaults standardUserDefaults] registerDefaults:@{@"UserAgent":customerUA}];
在建立webview时,QHBaseWebLoader
里建立代理监听
// 建立webView容器 WKWebViewConfiguration *webConfig = [[WKWebViewConfiguration alloc] init]; WKUserContentController *userContentVC = [[WKUserContentController alloc] init]; webConfig.userContentController = userContentVC; WKWebView *wk = [[WKWebView alloc] initWithFrame:CGRectZero configuration:webConfig]; [self.view addSubview:wk]; self.wv = wk; self.wv.navigationDelegate = self; self.wv.UIDelegate = self; self.wv.translatesAutoresizingMaskIntoConstraints = NO; ... self.bridge = [WKWebViewJavascriptBridge bridgeForWebView:self.wv]; [self.bridge setWebViewDelegate:self]; [self.wv.configuration.userContentController addScriptMessageHandler:self.bridge name:@"WKWebViewJavascriptBridge"];
而后h5
中经过如下调用:
window.webkit.messageHandlers.WKWebViewJavascriptBridge.postMessage(...);
而后WKWebViewJavascriptBridge
内部,接受传递的信息,并自行解析
#pragma mark - WKScriptMessageHandler - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message { if ([message.name isEqualToString:@"WKWebViewJavascriptBridge"]) { [self excuteMessage:message.body]; } }
iOS中还有一点和Android不一样就是,不少标准的HTML5内容无需额外兼容(譬如fileinput文件选择等)
其它内容,和Android实现中提到的同样,这里就再也不赘述了,能够直接参考源码
另外,后续若是继续有容器优化等操做,也会单独整理,加入本系列。
为了方便,直接集成到了res/
中,入口页面默认会加载它,也能够直接看源码
github
上这个框架的实现