Xcode能夠直接引入h5的界面,實現原生界面內嵌h5開發。其實這裏不止iOS能夠這樣作,安卓也能夠引用一樣的h5界面,實現界面使用同一份h5代碼。css
爲何要寫h5的界面呢,緣由是第一Xcode很卡,畫圖效果也不如h5方便。第二是調試h5直接經過瀏覽器調試就好了,不像Xcode每次編譯跑起來真是卡的一批,時間又長。 因此我就研究了這一套本地h5開發的邏輯,既能很好的實現業務邏輯的開發,又能方便開發,統一多端,效率大大提高。html
步驟以下vue
把目錄導入到Xcode中,選擇Create folder references點擊完成java
引入h5目錄效果如上git
下面從實現界面和實現邏輯兩個部分講解。github
上面是實現的h5界面,經過webview引入項目,能夠看到效果和原生幾乎同樣。web
固然須要達到和原生效果同樣,還要對h5的界面作一些配置。api
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
<meta name="format-detection" content="telephone=no" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black">
複製代碼
上面的配置規定了頁面的不能縮放,數字不會直接顯示號碼的樣式,還要狀態欄的顯示顏色爲黑色跨域
/* 禁用長按 */
body {-webkit-touch-callout:none;/*系統默認菜單被禁用*/-webkit-user-select:none;/*webkit瀏覽器*/-khtml-user-select:none;/*早起瀏覽器*/-moz-user-select:none;/*火狐瀏覽器*/-ms-user-select:none;/*IE瀏覽器*/user-select:none;/*用戶是否可以選中文本*/}
html{
font-family:PingFangSC-Regular;
}
複製代碼
上面是一些通用的css配置,我放到了style.css裏面,一是禁止用戶長按顯示放大顯示器的效果,二是統一使用蘋方字體。瀏覽器
有了以上配置,基本就能夠好好實現界面的開發了,開發h5的流程沒有和正常h5開發沒有什麼流程。
iOS引入資源的方式以下
let configuration = WKWebViewConfiguration()
configuration.preferences = WKPreferences()
configuration.preferences.javaScriptEnabled = true
configuration.userContentController = WKUserContentController()
let webview = WKWebView.init(frame: self.view.bounds, configuration: configuration)
self.view.addSubview(webview)
webview.navigationDelegate = self
webview.load(URLRequest.init(url: URL.init(fileURLWithPath: Bundle.main.path(forResource: "licheng", ofType: "html", inDirectory: "h5")!)))
複製代碼
webview引入licheng.html,經過urlrequest請求資源,渲染到當前的webview界面上,因爲是本地直接加載,不存在網絡延遲的問題,因此加載速度很快,幾乎和原生界面同樣。
下面講講邏輯部分,好比網絡,點擊跳轉,傳值等。
以前的博客也有講過wkwebview混合開發,怎麼實現傳值的方式。主要過程就是實現js和原生交互,有了交互外加一層封裝,就能夠方便的經過接口實現咱們傳值功能。
添加一個name的handler,h5能夠經過發送這個handler,調用原生的代理方法
func addJsFunc(_ name: String, _ callback:@escaping ((Any)->Void)) {
wkconfiguration.userContentController.add(self, name: name)
jsFuncArr.append(JsFuncModel.init(name: name, callback: callback))
}
複製代碼
h5發送handler
window.webkit.messageHandlers.openvc.postMessage({name:'aa', sex:'male', age:21})
複製代碼
原生代理方法接收,匹配到相應的name,執行原生的callback
public func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
print(message.name)
print(message.body)
for jsFunc in jsFuncArr {
if jsFunc.name == message.name {
jsFunc.callback(message.body)
break
}
}
}
複製代碼
以上是添加一個handler的方式,可使js調用原生並傳值。這樣就能實現界面之間的跳轉的action,以及js一些傳值動做的執行了。
下面實現原生傳值給js環境
func addJsObj(_ key: String, _ value: String) {
wkwebview.evaluateJavaScript("vm.\(key) = \(value)", completionHandler: nil)
}
複製代碼
經過kv的方式設置vm的屬性值,vm是咱們vue全局環境的實例。咱們的h5的組件是經過vue完成雙向綁定的,經過設置vm的屬性的值, 能夠把data迅速的渲染到咱們的頁面上。這裏引入vue這個框架的好處是,咱們不用那麼頻繁的操做dom了, 有vue作mvvm的架構,界面的渲染真是比原生實現輕鬆太多了。
以上是原生經過evaluateJavaScript傳值給js環境,這樣就能實如今原生實現網絡請求回來的數據,直接給到h5界面去渲染。或者原生的一些動做能夠通知到h5去執行。
注意這裏網絡請求是放在原生環境實現的,緣由是瀏覽器和後臺部署都是不支持跨域訪問的,這個問題能夠具體google。
經過上面的開發基本上能夠實現h5的原生開發了,由於h5是打包到項目裏面的,因此性能很好。 我對這一套渲染和傳值的邏輯進行了封裝,放在了JWebViewController裏面,繼承該類就可使用了。 代碼參考iOSh5vue
頂層文件夾名字要命名爲h5,由於JWebViewController底層封裝寫死了h5的目錄。
在頁面返回時,要作合適的時機調用clearJs方法,這樣vc纔會被析構。否則會出現內存泄露。
相關邏輯都封裝在JWebViewController裏面了,須要繼承JWebViewController,實現業務邏輯的部分。