introduce
Xcode can be directly introduced into the H5 interface to achieve native interface embedded in H5 development. In fact, not only iOS can do this, Android can also reference the same H5 interface, implementation of the interface using the same H5 code.
Why do I write the interface of H5? The reason is that the first Xcode is very slow and the drawing effect is not as convenient as H5. The second is to debug H5 directly through the browser debugging line, unlike Xcode each compilation run is really a batch of cards, and a long time. Therefore, I studied this set of local H5 development logic, which can not only well realize the development of business logic, but also convenient development, unified multi-terminal, and greatly improve efficiency.
Complete the following steps
Import the directory into Xcode, select Create Folder References and click Finish
Introducing the H5 directory looks like this
The following from the implementation of the interface and the implementation of logic two parts.
Implement interface
Above is the implementation of the H5 interface, through the WebView to introduce the project, you can see that the effect is almost the same as the native.
Of course, it needs to be the same as the original, and there are some modifications to the H5 interface.
<meta name="viewport" content="Width = device - width, initial - scale = 1.0, the 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">
Copy the code
The above configuration stipulates that the page cannot be zoomed, that numbers do not display numbers directly, and that the color of the status bar should be black
/* Disable long press */ body {-webkit-touch-callout:none; /* The system default menu is disabled */-webkit-user-select:none; /*webkit browser */-khtml-user-select:none; /* early browser */-moz-user-select:none; /* firefox */-ms-user-select:none; /* Internet explorer */user-select:none; } HTML {font-family: pingfangsc-regular; }Copy the code
Here are some general CSS configurations, which I put in style.css. One is to prohibit the user from holding down the display to enlarge the display, and the other is to use the Apple font uniformly.
With the above configuration, the basic can be a good implementation of the interface development, the development of H5 process and normal H5 development process.
IOS introduces resources in the following ways
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")!)))
Copy the code
Webview introduces licheng. HTML, requests resources through URlRequest, and renders to the current WebView interface. Since it is directly loaded locally, there is no problem of network delay, so the loading speed is fast, almost the same as the native interface.
Let’s talk about the logical parts, like networking, clicking to jump to, passing values, etc.
Implementation logic
The previous blog also talked about wKWebView hybrid development, how to achieve the way of passing values. The main process is to achieve JS and native interaction, with interaction plus a layer of encapsulation, we can easily achieve the value function through the interface.
Add a handler for name that H5 can send to invoke the native proxy method
func addJsFunc(_ name: String, _ callback:@escaping ((Any)->Void)) {
wkconfiguration.userContentController.add(self, name: name)
jsFuncArr.append(JsFuncModel.init(name: name, callback: callback))
}
Copy the code
H5 send handler
window.webkit.messageHandlers.openvc.postMessage({name:'aa', sex:'male', age:21})
Copy the code
The native proxy method receives, matches the corresponding name, and performs the native 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}}}Copy the code
This is the way to add a handler to make js calls native and pass values. This can realize the interface between the jump action, as well as some of the JS transfer value of the action.
The following implementation of native values to the JS environment
func addJsObj(_ key: String, _ value: String) {
wkwebview.evaluateJavaScript("vm.\(key) = \(value)", completionHandler: nil)
}
Copy the code
Set the attribute value of VM in kv mode. Vm is an instance of our VUE global environment. Our H5 components are bidirectional bound through VUE. By setting the value of vm attributes, data can be quickly rendered to our page. The advantage of introducing vue here is that we don’t have to manipulate the DOM so much. With Vue as the architecture of MVVM, interface rendering is much easier than the native implementation.
The evaluateJavaScript is used natively to pass values to the JS environment, so that the data requested from the native-implementation network can be rendered directly into the H5 interface. Or native actions can be notified to H5 for execution.
Note that the network request is implemented in the native environment, because the browser and background deployment do not support cross-domain access, this problem can be specific to Google.
Through the above development can basically achieve the native development of H5, because H5 is packaged into the project, so the performance is very good. I’ve wrapped this set of render and pass logic into a JWebViewController, which can be used by inheriting the class. Code reference iOSh5vue
Matters needing attention
-
The top-level folder is named H5 because the JWebViewController wrapper has written the h5 directory.
-
When the page returns, call the clearJs method at the right time so that the VC is destructed. Otherwise there will be a memory leak.
-
The relevant logic is encapsulated in JWebViewController, need to inherit JWebViewController, the implementation of the business logic part.