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
上這個框架的實現