preface

In recent years, hybrid development has become more and more popular. Today I want to write an interaction between WKWebView and Cordova.

1: Create the first Cordova project

Open the terminal, CMD to switch to the working directory, enter the following command, again, this may take some time to complete
cordova create Demo com.cordova.demo.hello HelloWorld
Copy the code

2: Add platform support

All subsequent commands are executed in the project directory, and CMD can be switched to the project directory in any subdirectory of the project
cd Demo
Copy the code
Before building a project, you need to specify a set of target platforms. Your ability to run these commands depends on whether your machine supports each SDK, and if the SDK is properly installed. Run the following command on a MAC:
 cordova platform add ios
Copy the code

3: View the supported platforms and added platforms of Cordova

cordova platforms ls
Copy the code

4: Add plug-ins

cordova plugin add cordova-plugin-device
Copy the code

5: View plug-ins

cordova plugin list
Copy the code

6: Add wkWebView plug-in

cordova plugin add cordova-plugin-wkwebview-engine
Copy the code

7: In the iOS project, use Cocoapods in the podfile below,pod Install

platform :ios,'9.0'
inhibit_all_warnings!
target 'WKWebiveCordova' do
   pod 'cordova-plugin-device'
   pod 'cordova-plugin-wkwebview-engine
end
Copy the code

8: Pull in WWW file to enter iOS project

Each of the two marked files and folders below (Cordova project) will be moved to (iOS project), note that (Cordova project)/platforms/ iOS folder below the directory structure is organized by me. Pull in the ios project and check create Folder References to make it blue

9: Check the blue folder directory, only android under platform is android, other folders are common with Android, and the method name of interaction should be the same.

10: config.xml configuration description

<content src="index.html" />
Copy the code
Local configuration of idnex.html, start wkWebView, if startPage is not written then start the HTML file by default.

When you load the WkWebView, remember to load the config. XML file, and the code will show you the jump URL screen, which will show you the configuration:

<feature name="IntentAndNavigationFilter">
         <param name="ios-package" value="CDVIntentAndNavigationFilter" />
         <param name="onload" value="true" />
 </feature>

 <feature name="CDVWKWebViewEngine">
      <param name="ios-package" value="CDVWKWebViewEngine" />
 </feature>

 <allow-navigation href="http://*/*" />
 <allow-navigation href="https://*/*" />
 <allow-navigation href="*" />
 <preference name="CordovaWebViewEngine" value="CDVWKWebViewEngine" />
 <plugin name="cordova-plugin-wkwebview-engine" spec="^ 1.2.1." " />
Copy the code

11: Create a new WKWebview file inheriting CDVViewController to show loading WKWebview

The wkwebView.h file is as follows
#import <WebKit/WebKit.h>
#import <UIKit/UIKit.h>
#import <Cordova/CDVViewController.h>
#import <Cordova/CDVCommandDelegateImpl.h>
#import <Cordova/CDVCommandQueue.h>NS_ASSUME_NONNULL_BEGIN @interface WKWebview : CDVViewController + (WKWebview *)shareInstance; // Set this value to load the current page @property (nonatomic, copy) NSString *webUrl; webView@property (nonatomic, strong) WKWebView *currentWebView; @end NS_ASSUME_NONNULL_ENDCopy the code
The wkWebView. m file is as follows
#import "WKWebview.h"
@interface WKWebview ()
@end

@implementation WKWebview

- (instancetype)init {
    self = [super init];
    if (self) {
        self.configFile   = [self configPath];
    }
    return self;
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onNotification:)
    name:CDVPluginResetNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self
    selector:@selector(onNotificationed:)
    name:CDVPageDidLoadNotification object:nil];
     [self setWebViewBackground];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view
    self.currentWebView = (WKWebView *)self.webView;
    self.webView.backgroundColor = [UIColor redColor];
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:CDVPluginResetNotification object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:CDVPageDidLoadNotification object:nil];
}

- (NSString *)configPath {
    NSString *path = [[NSBundle mainBundle]pathForResource:@"config" ofType:@"xml"];
    NSLog(@"path===== %@",  path);
    return path;
}

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)onNotification:(NSNotification *)notification {
    NSLog(@"Webview starts loading");
    WKWebView *webview = notification.object;
    if(! [[webview.URL absoluteString] containsString:@"www/error.html"]) {}if ([webview.URL.absoluteString isEqualToString:@"ios:backtotheroot"]) {
        [self.navigationController popViewControllerAnimated:YES];
    }
}
//wkwebView
- (void)onNotificationed:(NSNotification *)notification {
    NSLog(@"Webview loaded."); WKWebView *webview = notification.object; // Remove the text checkbox that appears after long pressing [webview evaluateJavaScript:@]"document.documentElement.style.webkitUserSelect='none';" completionHandler:^(id obj, NSError *error){
    }];
    [webview evaluateJavaScript:@"document.title" completionHandler:^(id obj, NSError *error) {
        if([obj isKindOfClass:[NSString class]]) { self.title = (NSString *)obj; }}]; } - (void)setWebUrl:(NSString *)webUrl {
    if(! webUrl) {return;
    }
    _webUrl = webUrl;
    if (self.currentWebView) {
        NSURL *url = [NSURL URLWithString:[webUrl stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]];
        NSURLRequest *request = [NSURLRequest requestWithURL:url];
        [self.currentWebView loadRequest:request];
    }
}

- (void)setWebViewBackground {
    NSLog(@"self.startPage==%@", self.startPage);
    if ([self.startPage containsString:@"hsjob"]) {
        self.view.backgroundColor = [UIColor redColor];
    } else if ([self.startPage containsString:@"hstravel"]) {
        self.view.backgroundColor = [UIColor redColor];
    } else if ([self.startPage containsString:@"movie"]) {
        self.view.backgroundColor = [UIColor blackColor];
    }
}
@end
Copy the code

12: Start the remote URL display wkWENView interface call

 WKWebview *vc = [[WKWebview alloc] init];
 vc.startPage = @"http://www.baidu.com";
 vc.hidesBottomBarWhenPushed = NO;
 [self.navigationController pushViewController:vc animated:YES];
Copy the code

13: Add vc.startPage = @”www.baidu.com”; By default, index. HTML is displayed. It is used to implement interactive demo of original audio and HTML

14: Create a new CDVPlugin that inherits the CDVPlugin as a bridge call between the original sound and HTML5

MyPlugi. H file
#import "CDVPlugin.h"
#import <Cordova/CDVPlugin.h>NS_ASSUME_NONNULL_BEGIN @interface MyPlugin: CDVPlugin - (void)currentPosition: CDVInvokedUrlCommand *command;
@end
NS_ASSUME_NONNULL_END
Copy the code
MyPlugi. M file
#import "MyPlugin.h"- (void)currentPosition:(CDVInvokedUrlCommand *)command {
     NSLog(@"Command is the argument to the callback.");
    CDVPluginResult *result2 = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsArray:@[ @"data1"The @"data2" ]];
    [self.commandDelegate sendPluginResult:result2 callbackId:command.callbackId];
}
@end
Copy the code

15: In the config. XML file configuration this file is as follows

  <feature name="MyPlugin">
      <param name="ios-package" value="MyPlugin" />
  </feature>
Copy the code

16: the index. HTML file is configured as follows

      <script type="text/javascript" src="./platform/common/loader.js"></script> // Can execute js <script in paralleltype="text/javascript">
            var loadList = ["./platform/common/hsplatform.js"];
            var u = navigator.userAgent;
            var isAndroid = u.indexOf("Android") > -1 || u.indexOf("Adr") > 1; Var isiOS =!! u.match(/\(i[^;] +; ( U;) ? CPU.+Mac OS X/); // Inside the app, I need to determine the difference between loading Android or ios. I will default to iosif (u.indexOf("_hsApp_") != -1) {
              var cordovaURL = "./platform/ios/cordova.js";
              if (isiOS) {
                cordovaURL = "./platform/ios/cordova.js";
              }
              loadList.push(cordovaURL, "./js/index.js");
            }else{
                var cordovaURL = "./platform/ios/cordova.js";
                if (isiOS) {
                  cordovaURL = "./platform/ios/cordova.js";
                }
                loadList.push(cordovaURL, "./js/index.js");
            }
            Loader.load(loadList);
        </script>
Copy the code

17: Modify the index.js file

document.addEventListener("deviceready", onDeviceReady, false);

function onDeviceReady() {
    console.log("Ready"); Cordova. Exec (successCurrentPosition, errorCurrentPosition,"MyPlugin"."currentPosition", [argument]); / ***successCurrentPosition callback successful errorCurrentPosition callback failed MyPlugin Our new file name currentPosition call method argument ***/function currentPosition() {
    console.log("This feature can only be used inside the APP.");
    var argument = JSON.stringify({
        'relocation': 'false'
    });
    Cordova.exec(successCurrentPosition, errorCurrentPosition, "MyPlugin"."currentPosition", [argument]); } // Successfully callback to get the current locationfunctionsuccessCurrentPosition(position) { console.log(position); } // Failed to get the current location callbackfunction errorCurrentPosition(position) {
    console.log(position);
}
Copy the code

18: in order for index.js to print console.log, add to index.html

<script src="https://cdn.bootcss.com/vConsole/3.2.0/vconsole.min.js"></script>
Copy the code
In the config. The XML configuration
<feature name="Console">
    <param name="ios-package" value="CDVLogger" />
    <param name="onload" value="true" />
</feature>
Copy the code

19: Click h5 interface to realize using native interaction as follows, print out

2022-07-07 05:05:57.442579+0800 WKWebiveCordova[74344:646107] This feature can only be used within the APP WKWebiveCordova[74344:646107]commandWKWebiveCordova[74813:651778] error==data1,data2Copy the code

20: Do you need to call back to HTML5 using the self.commandDelegate sendPluginResult method

21: Native to HTML5, from HTML5 to native interaction is done, need other plug-in interaction can be added to the WWW directory, and MyPlugin file extension. Upload the demo to Github