preface
Within three days of the New Year’s Day of 2018, I made a surprise attack with my friends, barely making the prototype, and gradually improved the subsequent API. (Of course, the main force is still that friend, I just started iOS, can barely understand, modify it)
The general content is as follows:
-
The JSBridge core interaction part
-
UI, Page and other common API implementation (other gradually improved)
-
Implementation of component (custom) API extensions
-
The API’s permission validation allows only one entry, emulating the simplest implementation
-
Other mechanisms such as offline resource loading updates and low-level optimizations are not available for the time being
Project structure
For convenience in this project, instead of splitting into static libraries (as you could), you put them all in one project
The overall directory structure is as follows:
quickhybrid-ios
|- AppDelegate // Application entry, distribution into the corresponding viewController
|- core // Core utility classes, put some general utility classes
| |- ui
| |- util
| |- ...
|- quickhybrid // JSBridge implementation of the core code, custom viewController, implementation API, etc
| |- WebViewJavascriptBridge
| |- basecore
| |- quickcore
| |- api
Copy the code
The code architecture
As with Android, it’s still a simple three-fold architecture: underlying core tool classes ->JSBridge implementation -> App implementation
Of these, Core and JsBridge can be packaged as static libraries if necessary
core
|- ui // Some UI effects are defined and implemented
|- util // Generic utility class
quickhybird
|- WebViewJavascriptBridge // Third party open source implementation of JsBridge, which has been modified
|- basecore // Define the base class viewController
|- quickcore // Define the viewController implementation in QuickHybrid
|- api // Define API to open native functionality to H5| - AppDelegate in application// Application entry, distribution into the corresponding viewController
|- MainViewController // The entry interface
|- TestPayApi // Define a test payment component (custom) API
|- qhjsmodules.plist // Internally define the module alias in the path relationship configuration file
Copy the code
Access configuration
IOS can configure permissions directly in info.plist, for example
<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> </dict> <key>NSCameraUsageDescription</key> <string> Is the application allowed to use the camera? < / string > < key > NSLocationWhenInUseUsageDescription < / key > < string > whether to allow the application USES location function < / string > The < key > NSMicrophoneUsageDescription < / key > < string > allow applications to use the microphone? < / string > < key > NSPhotoLibraryUsageDescription < / key > < string > is allowed to access the album < / string > < key > UIFileSharingEnabled < / key >...Copy the code
Application configuration
Bundle Identifier: com.quickhybrid.quickhybriddemo
Version: 1.0. 0
Deployment Target: 11.2Devices: Universal Signing: NoneCopy the code
Compared to the complicated configuration on Android, iOS is definitely much simpler and can be debugged with the latest system…
At this point, the project still has a lot of APIS left unimplemented, and some static libraries are expected to be introduced later.
Of course, if you want to introduce static library, it is also simple, directly like:
Project configuration ->Build Phases->Link Binary With Libraries->+ (add) -> then need to use the placesimportCan beCopy the code
The whole process was very relaxed and enjoyable.
Some key code
Code aspect, also cannot explain all one by one, here only enumerates some more important steps to achieve, the rest can refer to the source code
UA agreed
The UA convention has been mentioned in the previous JS project, that is, when loading the Webview, the following UA logo is uniformly added to the webview
// Get the default 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}];
Copy the code
Listen for JSBridge triggers
When creating a WebView, a proxy listener is created in QHBaseWebLoader
// Create webView containerWKWebViewConfiguration *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"];
Copy the code
Then the following call is made in H5:
window.webkit.messageHandlers.WKWebViewJavascriptBridge.postMessage(...) ;Copy the code
Then WKWebViewJavascriptBridge inside, accept the message, and resolve on its own
#pragma mark - WKScriptMessageHandler - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message { if ([message.name isEqualToString:@"WKWebViewJavascriptBridge"]) { [self excuteMessage:message.body]; }}Copy the code
other
There is also a difference between iOS and Android in that a lot of standard HTML5 content doesn’t require additional compatibility (fileInput file selection, etc.)
Other content, as mentioned in the Android implementation, will not be described here, you can refer to the source code
In addition, if there are further container optimization operations, they will be separately sorted and added to this series.
Front-end page Example
For convenience, it is integrated directly into RES /. The entry page loads it by default, or you can read the source code directly
Back to root
- How to implement a Hybrid framework
The source code
Github implements the framework
quickhybrid/quickhybrid