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