Cordova和Html交互

前言

最近几年混合开发越来越火,今天想写一个wkwebview和cordova的交互。

1: 创建第一个Cordova工程

打开终端,cmd切换目录到工作目录下,输入以下命令,同样,可能需要点时间来完成
cordova create Demo com.cordova.demo.hello HelloWorld
cordova_create_01.png

2: 添加平台支持

所有后续命令在项目的目录中进行,可在该项目任何子目录中,cmd切换到项目目录下
cd Demo
在构建项目之前,你需要指定一组目标平台。你能够运行这些命令取决于您的机器是否支持每一个SDK,合理是否已安装SDK。在MAC上运行命令:
 cordova platform add ios

3: 查看Cordova支持平台以及已经添加的平台

cordova platforms ls
cordova_addios_02.png

4: 添加插件

cordova plugin add cordova-plugin-device

5: 查看插件

cordova plugin list
cordova_addplugin_03.png

6: 添加wkwebview插件

cordova plugin add cordova-plugin-wkwebview-engine

7: 在iOS项目,并使用cocoapods在,podfile文件如下,pod install

platform :ios,'9.0'
inhibit_all_warnings!
target 'WKWebiveCordova' do
   pod 'cordova-plugin-device'
   pod 'cordova-plugin-wkwebview-engine
end
cordova_addpod_04.png

8 :拉入www文件进入iOS项目

在(cordova项目)下面两个标记出来的文件和文件夹移动到(iOS项目)中,注意是(cordova项目)/platforms/ios文件夹下面的被我整理下目录结构。拉入ios项目,记得这样勾选create folder references,才会变成蓝色文件夹
cordova_set_05.png

9: 查看蓝色文件夹目录,其中只有platform下的android是安卓那边的,其他文件夹都是和安卓公用,等下交互的方法名要一样。

cordova_addpod_06.png

10: config.xml配置说明

<content src="index.html" />
本地的配置的idnex.html,启动wkwebview,如果startPage 没有写则是默认启动这个html文件。

加载wkwebview时候,要记得载入config.xml文件,代码下面会显示
跳转url界面能显示出来配置如下东西:

<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" />

11: 新建一个WKWebview文件继承CDVViewController 来显示加载wkwebview

WKWebview.h文件如下
#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;
//设置这个值,加载当前页面
@property (nonatomic, copy) NSString *webUrl;
//当前页面webview
@property (nonatomic, strong) WKWebView *currentWebView;
@end
NS_ASSUME_NONNULL_END
WKWebview.m文件如下
#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开始加载");
    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加载完成");
    WKWebView *webview = notification.object;
    //去除长按后出现的文本选取框
    [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

12: 启动远程url显示wkwenview界面调用

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

13: 把vc.startPage = @"http://www.baidu.com"; 屏蔽掉,默认显示出index.html,用来实现原声和html的交互demo

cordova_start_08.png

14: 新建一个CDVPlugin继承CDVPlugin 来作为原声和html5的桥接调用

MyPlugi.h文件
#import "CDVPlugin.h"
#import <Cordova/CDVPlugin.h>
NS_ASSUME_NONNULL_BEGIN
@interface MyPlugin : CDVPlugin
// 获取当前位置信息
- (void)currentPosition:(CDVInvokedUrlCommand *)command;
@end
NS_ASSUME_NONNULL_END
MyPlugi.m文件
#import "MyPlugin.h"
@implementation MyPlugin
//获取当前位置信息
- (void)currentPosition:(CDVInvokedUrlCommand *)command {
     NSLog(@"command是回调的参数,在里面取");
    CDVPluginResult *result2 = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsArray:@[ @"data1", @"data2" ]];
    [self.commandDelegate sendPluginResult:result2 callbackId:command.callbackId];
}
@end

15: 在config.xml文件配置下这个文件如下

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

16: index.html文件配置如下

      <script type="text/javascript" src="./platform/common/loader.js"></script> // 能并行执行js
        <script type="text/javascript">
            var loadList = ["./platform/common/hsplatform.js"];
            var u = navigator.userAgent;
            var isAndroid = u.indexOf("Android") > -1 || u.indexOf("Adr") > -1; //android终端
            var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
            //app内部 这里需要判断加载安卓或者ios的区别,我就默认为ios了
            if (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>

17: 修改下index.js文件

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

function onDeviceReady() {
    console.log("准备");
}

// 获取当前位置
Cordova.exec(successCurrentPosition, errorCurrentPosition, "MyPlugin", "currentPosition", [argument]);
/ ***successCurrentPosition 成功回调
errorCurrentPosition 失败回调
MyPlugin 我们新建的文件名字
currentPosition 调用方法
argument 入参***/
function currentPosition() {
    console.log("该功能只能在APP内部使用");
    var argument = JSON.stringify({
        'relocation': 'false'
    });
    Cordova.exec(successCurrentPosition, errorCurrentPosition, "MyPlugin", "currentPosition", [argument]);
}

//获取当前位置成功回调
function successCurrentPosition(position) {
    console.log(position);
}
//获取当前位置失败回调
function errorCurrentPosition(position) {
    console.log(position);
}

18: 为了index.js能正常打印console.log,在index.html上加上

<script src="https://cdn.bootcss.com/vConsole/3.2.0/vconsole.min.js"></script>
在config.xml配置
<feature name="Console">
    <param name="ios-package" value="CDVLogger" />
    <param name="onload" value="true" />
</feature>

19: 点击h5界面 实现使用原生的交互如下,打印出

2022-07-07 05:05:57.442579+0800 WKWebiveCordova[74344:646107] 该功能只能在APP内部使用
2020-07-07 05:05:57.445205+0800 WKWebiveCordova[74344:646107] command是回调的参数,在里面取
2020-07-07 05:15:08.682174+0800 WKWebiveCordova[74813:651778] error==data1,data2

20: 是否需要回调到html5 用self.commandDelegate sendPluginResult方法

21: 原生到html5,从html5到原生的交互就说完了,需要其他的插件交互都可以在这个www目录上增加,和MyPlugin文件扩展。demo会上传到github上去

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 210,978评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,954评论 2 384
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,623评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,324评论 1 282
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,390评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,741评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,892评论 3 405
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,655评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,104评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,451评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,569评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,254评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,834评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,725评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,950评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,260评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,446评论 2 348