Cordova开发指南

作者: 陵无山 | 来源:发表于2018-12-21 10:18 被阅读179次

    通过一个月的Cordova学习, 我将知识点总结为三部分:

    1. 纯Cordova开发---不依赖原生平台
    2. 原生平台混合Cordova开发
    3. 插件开发

    在进行Cordova开发之前, 先花点时间了解一下的Cordova的原理和Cordova的框架结构.

    1. Cordova是开发跨平台web App的工具, 使用前端技术来开发App, 可以节省成本和快速发布.
    2. Cordova的底层逻辑是:HTML+CSS搭建页面, 使用JS和原生平台交互来展示原生平台的功能.
    3. Cordova所有功能是建立在各种插件上的, 所以插件开发是Cordova开发的重点.

    纯Cordova开发

    这种开发模式不需要各原生平台开发人员参与, 只需要前端猿将开发好的web App放入到Cordova工程中, 然后使用Cordova-CLI(Cordova命令行界面)将web App和各种插件配种好后, 就可以build, run进行各平台的构建和调试了. 以下是纯Cordova开发的步骤:

    1. Cordova的安装
    2. 使用Cordova-CLI创建Cordova项目----创建Cordova项目后, 前端猿就可以在www/进行开发, 今后的大部分工作都集中在这个文件下.
      1. 添加平台
      2. 添加插件
      3. 构建Cordova项目
      4. 在各原生平台上运行Cordova App
    3. Cordova项目更新

    一.Cordova的安装

    CLI工具需要使用npm来安装, 因为它被发布到了npm.
    按照下面步骤来按照CLI:

    1. 下载和安装Node.js.
    2. (可选)如果你的电脑没有安装Git的话, 下载和安装git client, 因为后续CLL需要使用git来下载git仓库中的资源. 各OS的安装方法自行百度.
    3. 使用Node.js中的npm来安装cordova模块. cordova模块会自动被npm下载.
      1. 在OS x和linux下

         $ sudo npm install -g cordova
        

        如果出现"xx/xx/xx(例如/usr/local/share) permission denyed"的错误,可以在npm命令前加上sudo前缀.

      2. 在window中

         C:\>npm install -g cordova
        

        上面的-g标志告诉npm全局安装cordova. 否则, 它将安装在当前工作目录的node_modules子目录中.

    安装之后, 你应该能够在命令行上运行cordova, 不需要参数, 它会打印帮助文本.

    二.创建Cordova工程

    1.使用CLI命令创建 create

    cd到维护源代码的目录, 并创建一个cordova项目:

    $ cordova create hello com.example.hello HelloWorld
    

    这将为你的cordova应用程序创建所需的目录结构. 默认情况下, cordova create脚本会生成一个基于Web的框架应用程序, 其主页是项目下www/目录中的index.html文件

    打开Mac终端输入上面的命令, 创建一个Cordova项目, 得到项目目录结构如下:


    15427793118491.jpg

    上面的Create命令的解释:

    1. 保存项目的路径, 比如上面的"hello", 该路径是缺省的.
    2. 项目的id, 默认值是io.cordova.hellocordova; 安卓中的Java包名, iOS的bundleID都需要用到这个, 所以最好不要缺省, 或者要好好对待这事, 该值以后可以修改.
    3. 项目的name, 默认是HelloCordova, 该值也可以修改, 安卓平台可能会使用该值作为类名.
    4. 上面idname的都会配到config.xml中
      15450994158002.jpg

    2.使用模板创建工程 --template

    使用模板App中的代码可以快速搭建你的cordova-app.

    1. 首先你要去npm网站上, 使用关键字cordova:template来搜索可以用的template. 如下图所示:

      15446646202387.jpg
    2. 这里我使用第二template-cordova-template-ngx-onsenui来创建一个项目, 可以的命令有如下:

    $ cordova create hello com.example.hello HelloWorld --template <npm-package-name>
    $ cordova create hello com.example.hello HelloWorld --template <git-remote-url>
    $ cordova create hello com.example.hello HelloWorld --template <path-to-template>
    
    1. 我选择第一个命令, 在我本地创建如下项目:
    cordova create UseCordovaTemplate personal.zxx.cordovatemplate --template cordova-template-ngx-onsenui
    

    无错执行完上面命令后, done! 使用模板生成了一个新项目.

    我们来看下, 使用模板创建的项目的和不是模板创建的区别:
    
    15446654222528.jpg
    发现多了几个文件和一个src文件夹.
    1. 接下来添加平台-iOS:
    cedardeiMac-6:Desktop zhouxingxing$ cd UseCordovaTemplate/
    cedardeiMac-6:UseCordovaTemplate zhouxingxing$ cordova platform add ios
    
    添加成功后, 会在`platforms/`生成一个iOS项目:
    
    15446659436862.jpg
    1. 然后我运行构建, 运行cordova项目
    cordova build ios 
    cordova run ios 
    

    发现一个错误:

    No target specified for emulator. Deploying to iPhone-X, 12.1 simulator
    /Users/zhouxingxing/Desktop/UseCordovaTemplate/platforms/ios/build/emulator/HelloCordova.app/Info.plist file not found.
    

    上网搜索, 发现是因为Xcode 10更新了构建系统, 但cordova并支持, 官方给出的解决方案是手动选择不适用系的构建系统:

    # Cordova CLI
    cordova run ios --buildFlag='-UseModernBuildSystem=0'
    cordova build ios --buildFlag='-UseModernBuildSystem=0'
    

    详细信息请参考:https://github.com/apache/cordova-ios/issues/407


    下面的添加平台platform/插件plugin/构建build/运行run这些命令都需要你刚才创建项目的路径下工作, 比如刚才的*/hello/.

    3.添加平台 platform

    1. 下面的这些命令必须在上面创建项目的目录下运行, 或者子目录也行
    $ cd hello
    
    1. 添加你App定位的平台. 我们将添加'ios'和'android'平台并确保它们保存到config.xml和package.json:
    $ cordova platform add ios
    

    添加完iOS后, 查看项目结构, 发现在platform目录下多了一个ios/, 里面的内容是一个iOS项目目录:

    15427803342837.jpg

    并且安装了一个叫cordova-plugin-whitelist的插件, 在plugins/也发现多了一个文件夹.

    同样安装Android平台后, `platform`也会多一个安卓项目:
        
        $ cordova platform add android
    
    1. 查看你添加的平台:
    $ cordova platform ls
    
    15427809918948.jpg
    运行添加或删除平台的命令会影响项目platform目录的内容, 其中每个指定的平台都显示为子目录

    注意:使用CLI构建应用程序时, 你不应编辑/platforms/目录中的任何文件. Cordova在准备构建应用程序或重新安装插件时, 会定期自动覆盖此目录中的文件.

    1. config.xml的变化


      15451003095257.jpg

    更多关于平台的操作(比如, 删除平台, 添加特定版本的平台, 从本地添加平台)请看参考Cordova-CLI参考

    4.添加插件 plugin

    插件的定义:

    1. 插件是指能够使Cordova WebView和相应原生平台就行交互的注入代码包. 插件给基于Web的App提供对原生设备和平台功能的访问.
    2. 本质上是一个js文件+原生类(比如Android的Java类,iOS的OC类), JavaScript接口供前端调用,这影藏了背后的各种native代码的实现.

    插件添加和删除

    1. 插件添加可以通过插件id和Git repo的url来添加:
        $ cordova plugin add cordova-plugin-xyprogress //通过插件id
        $ cordova plugin add https://github.com/cheerszhou/CordovaPulginForTest.git //通过Git url添加
    

    添加完插件后, 在项目目录的下plugins/会显示你添加的插件:

    15451029455183.jpg
    而且config.xml中也会注册这些插件:
    
    15451029967640.jpg
    1. 插件删除:
        $ cordova plugin rm cordova-plugin-xyprogress
    

    运行上面命令后, 在plugins/config.xml也会删除相应的插件

    1. 插件更新,先删除,后在添加:
    $ cordova plugin rm cordova-plugin-xxxx
    $ cordova plugin add cordova-plugin-xxxx
    
    1. 列举安装的插件:
    $ cordova plugin ls
    

    更多关于如何管理(按版本添加, 插件冲突)插件的命令请参考Cordova-CLI参考

    5.构建和运行

    创建项目, 添加平台和插件后, 你可以进行构建App了. 在构建之前, 你需要检查你的开发环境是否搭建好了, 因为构建各个平台的App需要的环境是不一样的, 比如iOS你需要安装Mac系统, Xcode, xcode-select, ios-deploy.

    1. 检查各平台需要的环境要求:
    $ cordova requirements
    

    运行上面命令, 你从terminal中可以看到如下提示信息, 安装提示信息去搭建各平台需要的环境:


    15427816348232.jpg

    关于各平台的构建环境, 请看:
    1. 安卓平台环境要求
    2. iOS平台环境要求
    3. Windows平台环境要求

    1. 使用$ cordova build构建所有平台项目, 也可以构建特定平台, 如iOS:
    $ cordova build ios
    

    更多关于build的命令请参考Cordova-CLI参考

    1. 使用$ cordova run来构建并运行所有平台, 也可使用下面带选项的命令:
    • 在Android平台上,名为Nexus_5_API_23_x86模拟器上运行的当前cordova项目的发布版本. 运行时使用特定构建配置:
    cordova run android --release --buildConfig=..\myBuildConfig.json --target=Nexus_5_API_23_x86
    
    • 使用真机或模拟器(如果没有连接设备)在Android平台上运行当前cordova项目的调试版本. 跳过构建:
    cordova run android --nobuild
    
    • 在ios设备上运行当前cordova项目的调试版本:
    cordova run ios --device
    
    • 枚举可用于运行此应用程序的所有连接设备和可用模拟器的名称:
    cordova run ios --list
    
    • 或者模拟器中运行:
    cordova emulate ios
    //指定模拟器使用的模拟设备:
    cordova emulate ios --target iPhone-6s
    cordova emulate ios --target iPhone-6s-Plus
    

    运行后, 默认显示的www下的index.thml页面,下面是iOS和Android运行效果图:

    15427936848078.jpg 15451048960901.jpg

    6.调试和测试

    1. 调试一般通过cordova run命令运行各平台模拟上, 可以直观看到结果

    2. Cordova创建的iOS/android平台项目是可以直接打开的. Xcode/Android Studio内置的调试/分析工具对你进行iOS/android插件开发时非常有用. 请注意, 在各平台IDE中打开项目时, 建议你不要在IDE中编辑代码. 这将会改变项目的platform文件夹(而不是www)中的代码, 并且更改可能会被覆盖. 相反, 你应该编辑www文件夹中的代码, 并通过运行cordova build复制你的更改到各个平台.

    3. 插件开发者如果要在native IDE中进行开发时, 可以用--link标志来将他们开发插件通过cordova plugin add加入项目中. 这样插件链接的文件会相互影响---platform中的插件文件改变会反映在插件的原文件中(反之亦然).

    4. 使用Safari和Chrome进行调试

    三.升级Cordova和项目

    1. 安装cordova工具后, 你始终可以通过运行以下命令将其更新到最新版本:
    $ sudo npm update -g cordova
    
    1. 使用此语法安装特定版本:
    $ sudo npm install -g cordova@3.1.0-0.2.0
    
    1. 运行cordova -v以查看当前正在运行的版本. 要查找最新发布的cordova版本, 你可以运行:
    $ npm info cordova version
    
    1. 要更新你要定位的平台:
    $ cordova platform update android --save
    $ cordova platform update ios --save
    ...etc.
    

    原生平台混合Cordova开发

    可以在原生App使用Cordova中的web页面, 这节分为块内容, 分别是:

    1. iOS项目中混合Cordova
    2. Android项目中混合Cordova

    在iOS项目中混合Cordova

    一.将Cordova项目资源添加到Xcode项目中

    1. 首先你有一个iOS原生项目, 比如CordovaHybridByPod

    2. 你有一个Cordova项目, 如果没有使用cordova create创建一个, 并添加iOS平台, 因为后面需要用到cordova项目中的内容

    3. 打开你的iOS项目, 然后将cordova中的顶层config.xml文件复制到iOS项目下, 并且选择Create groups for any added folders

      15451156495138.jpg
    4. CordovaLib/CordovaLib.xcodeproj复制到Xcode项目中

      15451164624141.jpg
    5. 在Xcode项目导航栏中选择CordovaLib.xcodeproj, 然后在File Inspector中, 设置LocationRelative to Group

      15451172791832.jpg
    6. 选中Xcode项目的target, 然后在Build Settings中的Other Linker Flags中添加-force_load-Objc

      15451175544109.jpg

      注:这里有个bug, 官网说添加-force_load-Objc, 发现添加-force_load后, 原生buildbuild报错. 所以网上有人推荐添加-all_load-Objc.

    7. 打开Build Phases中的Link Binaries with Libraries, 将下面的库添加进去:

    AssetsLibrary.framework
    CoreLocation.framework
    CoreGraphics.framework
    MobileCoreServices.framework
    
    15451177930921.jpg
    1. 打开Target DependenciesLink Binaries with Libraries都加入CordovaLibbuild后的产物CordovaLib.a, 如果看不到libCordova.a, 可以在Cordova项目目录下运行cordova build命令.

      15451193738756.jpg
    2. Build Settings中的Header Search Paths.加入下面这些值:

        "$(TARGET_BUILD_DIR)/usr/local/lib/include"
    "$(OBJROOT)/UninstalledProducts/include"
    "$(OBJROOT)/UninstalledProducts/$(PLATFORM_NAME)/include"
    "$(BUILT_PRODUCTS_DIR)"
    
    15451197053500.jpg

    二.使用CDVViewController

    1. 添加下面的头文件:
    #import<Cordova/CDVViewController.h>
    
    1. 创建一个新CDVViewController实例, 在其他地方使用时, 强引用它:
    CDVViewController* viewController = [CDVViewController new];
    
    1. (可选)设置wwwFolderName属性, 默认为www:
    viewController.wwwFolderName = @"myfolder";
    
    1. (可选),在config.xml<content>标签中设置start page, 也可以是本地文件:
    <content src="index.html"/>
    

    ...或者一个远程地址:

    <content src="http://apache.org" />
    
    1. (可选),设置属性useSplashScreen, 默认值为NO:
    viewController.useSplashScreen = YES;
    
    1. 设置view frame, 总要设置为最新的值:
    viewController.view.frame = CGRectMake(0,0,320,480);
    
    1. 添加Cleaver到view中:
    [myView addSubview:viewController.view];
    
    1. 首先我将cordova中的包含index.html添加到Xcode项目, 然后在ViewController.m中使用CDVViewController如下:
    ```
    //
    //  ViewController.m
    //  CordovaHybridByPod
    //
    //  Created by developer_zxx on 2018/12/13.
    //  Copyright © 2018 developer_zxx. All rights reserved.
    //
    #import "ViewController.h"
    #import <Cordova/CDVViewController.h>
    @interface ViewController ()
    @end
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
    }
    
    - (IBAction)showCordovaWebview:(UIButton *)sender {
        CDVViewController * cordovaVC = [[CDVViewController alloc]init];
        cordovaVC.wwwFolderName = @"www";
        [self presentViewController:cordovaVC animated:YES completion:nil];
    }
    @end
    
    ```
    
    1. 运行结果:


      15451218123026.jpg
    2. 之后Cordova中的webView就交给www下的前端资源来管理了


    在Android项目中混合Cordova

    1. 首先你有一个Android原生项目, 比如NativeProjectForAndroid

    2. 你有一个Cordova项目, 如果没有使用cordova create创建一个, 并添加Android平台, 因为后面需要用到cordova项目中的内容

    3. 将Cordova项目中的platforms/android/下的res/config.xml, assets/www/下的文件添加到你安卓项目相应的目录下

      15451299418564.jpg
    4. 将将Cordova项目中的platforms/android/下的CordovaLib作为Android项目的moudle导入

      15451304082351.jpg
    1. cordova-plugin-whitelist插件的Java实现类添加到Android项目,该类在platforms/android/src/java中可以找到.

      15451308578311.jpg
    2. 此时你可以在Android原生项目中使用CordovaActivity.java, 该类显示www下的资源, 在MainActivity.java中跳转到Cordova Webview中.

      15451311657579.jpg
    3. 运行结果:


      15451316891061.jpg

    插件开发

    Cordova项目中大量使用插件, 除了Cordova平台提供的核心插件外, 开发者需要针对一些额外需求自定义开发插件.

    一. 插件工作的原理

    • Cordova插件是通过JavaScript对外提供接口来访问native功能, 从而能让前端在web app中开发类似native的功能.
    • 每个JavaScript对外提供的方法最终是通过调用Cordova提供的cordova.exec方法来调用native中的方法
    • 插件中方法最终都是调用native方法, 所以需要相应的native方法实现
    • 插件开发包含三个主要部分分别是:JavaScript接口, 原生类的实现, config.xml配置文件

    二. 插件开发示例

    下面按步骤讲解一个插件开发,该插件实现toast功能

    A.搭建插件结构

    1. 当你打算去写一个插件时, 最好先去阅览一遍已存在的插件, 这样你就可以有的放矢, 并且可以去github看相应的源代码.
    2. 上面的插件结构你可以手动创建, 也可以使用plugman来帮你搭建, 最好使用plugman(如果没有安装, 可以使用npm install -g plugman)来搭建, plugman搭建如下:
    命令:plugman create --name [插件名] --plugin_id [插件ID] --plugin_version [插件版本号]
    例子:plugman create --name ZxxToast --plugin_id cordova-plugin-zxxToast --plugin_version 1.0.0
    
    15452197134048.jpg
    1. 上面的插件文件结构边包含:

      1. www,里面是一个js文件,插件的JavaScript接口部分
      2. src,原生平台代码实现,可以包含Android,iOS,WP等,你要支持哪个平台,就在下面创建一个平台子文件夹,如某个已经发布的插件:
      15451327489750.jpg
      1. config.xml, 该文件起配置作用,制定插件的关键信息,初始如下, 后面还需对其进行编辑:
        15452203423842.jpg

    B.创建JavaScript接口

    接下来是创建给前端调用的js接口,这里需要一些前端知识。

    1. 打开插件目录下www中的ZxxToast.js文件,在ZxxToast.js中提供你想要的输出的接口

      function ZxxToast() {
      }
      
      ZxxToast.prototype.optionsBuilder = function () {//构建传给native的参数
      
        // defaults
        var message = null;
        var duration = 1.0;
        var position = "center";
        var addPixelsY = 0;
      
        return {
          withMessage: function(m) {
            message = m.toString();
            return this;
          },
      
          withDuration: function(d) {
            duration = d.toString();
            return this;
          },
      
          withPosition: function(p) {
            position = p;
            return this;
          },
      
          withAddPixelsY: function(y) {
            addPixelsY = y;
            return this;
          },
      
          build: function() {
            return {
              message: message,
              duration: duration,
              position: position,
              addPixelsY: addPixelsY
            };
          }
        };
      };
      
      
      ZxxToast.prototype.showWithOptions = function (options, successCallback, errorCallback) {
        options.duration = (options.duration === undefined ? 'long' : options.duration.toString());
        options.message = options.message.toString();
        cordova.exec(successCallback, errorCallback, "Toast", "show", [options]);//调用原始api,Toast为原始类名 ,show为原始类提供的方法
      };
      //js 提供给外部的api
      ZxxToast.prototype.show = function (message, duration, position, successCallback, errorCallback) {
        this.showWithOptions(
            this.optionsBuilder()
                .withMessage(message)
                .withDuration(duration)
                .withPosition(position)
                .build(),
            successCallback,
            errorCallback);
      };
      
      
      ZxxToast.install = function () {
        if (!window.plugins) {
          window.plugins = {};
        }
      
        window.plugins.ZxxToast = new ZxxToast();
        return window.plugins.ZxxToast;
      };
      
      cordova.addConstructor(ZxxToast.install);
      

      上面的show方法就是对外提供的接口.

    2. JavaScript接口​​提供了前端接口, 使其成为插件中最为重要的部分. 你可以随意构建你的JavaScript接口, 但你必须在后面使用下面语法来调用cordova.exec和原生平台进行通信:

    cordova.exec(function(winParam) {}, 
             function(error) {},
             "service",
             "action",
             ["firstArgument", "secondArgument", 42, false]);
    

    下面解释每个参数的作用:

    • function(winParam) {}:一个成功回调函数. 如果exec调用成功, 该函数会被调用, 参数由你传入.
    • function(error) {}:一个错误回调函数. 如果操作完成失败, 该函数会调用.
    • service:用来被原生调用的服务名. 与之对应的是原生类, 更多信息在下面各平台的指导中.
    • action:用来被原生调用的动作, 与之对应的类, 请看原生平台指导
    • [/* arguments */]: 一组传给原生环境的参数

    C.原生平台对插件接口的实现

    这里先实现iOS平台的接口支持

    1. 因为插件类需要引用Cordova库的CDVPlugin类, 所以先创建一个空的Cordova项目, 然后添加iOS平台, 用到的命令如下:
    $ cordova create CordovaDemo
    $ cordova platform add ios
    $ cordova build ios 
    
    1. 用Xcode打开在刚才创建的Cordova项目下的platforms/ios/中的iOS工程:

      15452233552528.jpg
    2. 在Xcode中创建一个名为Toast的OC类:


      15452235505656.jpg

      上面的提供的方法, 在JavaScript接口中可以通过exec()方法中的action参数来指定.

    3. 类Toast的实现文件Toast.m如下:

      #import "Toast.h"
      #import "Toast+UIView.h"
      #import <Cordova/CDV.h>
      
      @implementation Toast
      
      - (void)show:(CDVInvokedUrlCommand*)command {
        NSDictionary* options = [command argumentAtIndex:0];
        NSString *message  = options[@"message"];
        NSString *duration = options[@"duration"];
        NSString *position = options[@"position"];
        NSNumber *addPixelsY = options[@"addPixelsY"];
        
        
        if (![position isEqual: @"top"] && ![position isEqual: @"center"] && ![position isEqual: @"bottom"]) {
          CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"位置参数无效. 有效的参数可选:top, center, bottom"];
          [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
          return;
        }
        
        NSTimeInterval durationMS ;
        if ([duration doubleValue] < 1.0) {
            CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"时间参数无效. 时间参数必须>1.0"];
            [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
            return;
        } else {
          durationMS = [duration doubleValue];
        }
        
        [self.webView makeToast:message
                       duration:durationMS
                       position:position
                     addPixelsY:addPixelsY == nil ? 0 : [addPixelsY intValue]
                           data:nil
                        styling:nil
                commandDelegate:self.commandDelegate
                     callbackId:command.callbackId];
        
        CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
        pluginResult.keepCallback = [NSNumber numberWithBool:YES];
        [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
      }
      
      - (void)hide:(CDVInvokedUrlCommand*)command {
        [self.webView hideToast];
        
        CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
        [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
      }
      
      @end
      
    4. 在刚才创建ZxxToast插件目录的src/创建一个文件名为iosandroid的文件夹(后续用),然后将将上面创建的native类实现copy进去, 如果原生类依赖某些第三库, 也要copy进去:

      15452250601299.jpg

    D.配置plugin.xml文件

    1. 添加原生平台配置

      <?xml version='1.0' encoding='utf-8'?>
      <plugin id="cordova-plugin-zxxToast" version="1.0.0" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
          <name>ZxxToast</name>
          <name>Toast</name>
          
          <description>
              让webview弹toast框
          </description>
          
          <author>zhouxingxing</author>
          
          <js-module name="ZxxToast" src="www/ZxxToast.js">
              <clobbers target="cordova.plugins.ZxxToast" />
          </js-module>
          
          <engines>
              <engine name="cordova" version=">=3.0.0"/>
          </engines>
          
          <!-- ios -->
          <platform name="ios">
              
              <config-file target="config.xml" parent="/*">
                  <feature name="Toast">
                      <param name="ios-package" value="Toast"/>
                  </feature>
              </config-file>
              
              <header-file src="src/ios/Toast+UIView.h"/>
              <source-file src="src/ios/Toast+UIView.m"/>
              <header-file src="src/ios/Toast.h"/>
              <source-file src="src/ios/Toast.m"/>
              
              <framework src="QuartzCore.framework" />
          </platform>
      </plugin>
      
      
    2. 上面的节点解释:

      • id:代表这个插件的唯一标示,在上传到npm后,用户都是通过这个插件id去下载的

      • <name>:这里name可以和id不一样的,这个name就是插件的name,没有其他对应关系

      • <js-module>:文件中可能会有多个js-module的,一个js-module就是一个调用的方式,这里用户调用的方式就是cordova.plugins.ZxxToast.xxxMethod,之后我们会对外提供toast这个方法,那调用方式就为cordova.plugins.ZxxToast.show

    有关更多plugin.xml配置的相关信息, 请参考重要配置文件plugin.xml

    F.插件调试

    这里的插件调试即需要前端知识, 也需要原生开发经验所以有点难度. 而且测试代码需要在前端页面上实现. 所以下面的部分测试内容有可能不是那么的好.

    1. 为你的插件创建一个package.json文件:

      ZXX_MBP:ZxxToast developer_zxx$ plugman createpackagejson /Users/developer_zxx/Desktop/cordova-plugin-zxxToast/ZxxToast //输入这个命令后, 命令行提示输入一些关键信息
      name: (cordova-plugin-zxxToast) zmmzxxx //你在npm注册的用户名
      version: (1.0.0) //版本
      git repository: //可以输入github仓库地址, 你可以将插件发布到github, 这里我还没创建, 在发布的时候再去github创建代码库
      author: zhouxingxing //作者
      license: (ISC) MIT //许可证
      About to write to /Users/developer_zxx/Desktop/cordova-plugin-zxxToast/ZxxToast/package.json:
      
      {
        "name": "zmmzxxx",
        "version": "1.0.0",
        "description": "\n        让webview弹toast框\n    ",
        "cordova": {
          "id": "cordova-plugin-zxxToast",
          "platforms": [
            "ios"
          ]
        },
        "keywords": [
          "ecosystem:cordova",
          "cordova-ios"
        ],
        "engines": [
          {
            "name": "cordova",
            "version": ">=3.0.0"
          }
        ],
        "author": "zhouxingxing",
        "license": "MIT"
      }
      Is this OK? (yes) //回车就好
      
    2. 创建一个用来测试插件的Cordova项目:

    $ cordova create TestCordovaPlugin
    $ cd TestCordovaPlugin/
    $ cordova platform add ios android
    
    1. 进入你上面创建的, 然后从本地添加你的插件:
    $ Cordova plugin add /Users/developer_zxx/Desktop/cordova-plugin-zxxToast/ZxxToast
    

    运行上面命令后, 打开TestCordovaPlugin项目, 在plugins/下发现了你开房的创建, 说明已经安装好了

    15452699436240.jpg
    1. 编写测试代码, 打开TestCordovaPlugin根目录www/下的index.html文件,添加一按钮<button onclick="window.app.showShortTop()">Toast showLongBottom</button>:
        <!DOCTYPE html>
    <html>
        <head>
            
            <meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; img-src 'self' data: content:;">
            <meta name="format-detection" content="telephone=no">
            <meta name="msapplication-tap-highlight" content="no">
            <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
            <link rel="stylesheet" type="text/css" href="css/index.css">
            <title>Hello World</title>
        </head>
        <body>
            <div class="app">
                <h1>Apache Cordova</h1>
                <div id="deviceready" class="blink">
                    <p class="event listening">Connecting to Device</p>
                    <p class="event received">Device is Ready</p>
                </div>
                <button onclick="window.app.showShortTop()">Toast showLongBottom</button> //在首页添加测试按钮
    
            </div>
            <script type="text/javascript" src="cordova.js"></script>
            <script type="text/javascript" src="js/index.js"></script>
    <script type="text/javascript" src="js/Toast.js"></script>
        </body>
    </html>
    
    
    15452714151725.jpg
    1. 打开www/js/下的index.js文件, 在里面直接引用插件的js接口:
        var app = {
        // Application Constructor
        initialize: function() {
            document.addEventListener('deviceready', this.onDeviceReady.bind(this), false);
        },
    
        // deviceready Event Handler
        //
        // Bind any cordova events here. Common events are:
        // 'pause', 'resume', etc.
        onDeviceReady: function() {
            this.receivedEvent('deviceready');
        },
    
        // Update DOM on a Received Event
        receivedEvent: function(id) {
            var parentElement = document.getElementById(id);
            var listeningElement = parentElement.querySelector('.listening');
            var receivedElement = parentElement.querySelector('.received');
    
            listeningElement.setAttribute('style', 'display:none;');
            receivedElement.setAttribute('style', 'display:block;');
    
            console.log('Received Event: ' + id);
            //测试
            window.plugins.ZxxToast.show('Hello World!!!','4','bottom' ,function(a){
            console.log('toast success: ' + a)
            }, function(b){
            alert('toast error: ' + b)
            })
        }
    };
    app.initialize();
    
    1. 使用cordova run ios运行项目, 看效果:
    15452738469378.jpg
    1. 然后你可以使用Xcode打开platforms/ios/下的项目进行调试, 你对下图标记的文件就行修改调试, 调好后, 将修改同步到插件中即可:
      15452741342015.jpg

    原因安卓平台的插件开发和发布, 和iOS类似, 只是语言和开发环境变了, 可以参考下面的文章:

    1. 使用plugman创建插件-android:https://blog.csdn.net/u014284625/article/details/79922677
    2. apache-cordova官方文档:https://cordova.apache.org/docs/en/latest/

    三. 发布插件

    插件的js接口, 原生代码都已经实现了, 那么你测好后, 就可以发布该插件了

    你可以将插件发布到任何基于npmjs的注册处, 但推荐的是npm注册处. 这样其他开发者能够使用plugman或cordova-cli来自动安装你的插件.

    1. 为了发布插件到npm, 你需要按照下面步骤:

      • 安装plugmanCLI:
      $ npm install -g plugman
      
      • 为你的插件创建一个package.json文件:
      $ plugman createpackagejson /path/to/your/plugin
      
      • 发布
      $ npm  adduser #假如你现在还没有账号
      $ npm  pbulish /path/to/your/plugin
      

      更多关于npm使用方法, 请参考npm文档中心的Publishing npm Packages

    2. 使用npm pbulish之前, 需要你将你的插件代码上传到github上面, 这样你可以使用Git管理对你的插件进行版本控制, cordova-cli也可以直接使用Git url来下载你的插件.

    四. 关于iOSWKWebView的使用

    由于iOS8 Apple开始推荐使用更先进的WKWebView, 所以在iOS的最新的版本中, 我们不得不使用WKWebView, Cordova默认支持UIWebView. 而想要使用WKWebView的话就需要使用核心插件cordova-plugin-wkwebview-engine

    使用方法:
    这个插件要求cordova的版本>4.0.0

    1. 安装发布版本:
    $ cordova create wkwvtest my.project.id wkwvtest
    $ cd wkwvtest
    $ cordova platform add ios@4
    $ cordova plugin add cordova-plugin-wkwebview-engine
    
    1. 安装测试版本:
    cordova create wkwvtest my.project.id wkwvtest
    cd wkwvtest
    cordova platform add https://github.com/apache/cordova-ios.git#master
    cordova plugin add https://github.com/apache/cordova-plugin-wkwebview-engine.git#master
    

    但是这个插件依然有些问题, 在Stack Overflow网站查资料时, 有人推荐使用cordova-plugin-ionic-webview

    参考文档

    1. iOS原生项目嵌入Cordova:https://blog.csdn.net/yl19920713/article/details/78487149
    2. 如何在原生工程中引入Cordova工程: https://blog.csdn.net/e20914053/article/details/50170487
    3. 手动创建插件目录:http://www.cocoachina.com/ios/20180608/23718.html
    4. 使用plugman创建插件-ios:https://blog.csdn.net/u014284625/article/details/80699275
    5. 使用plugman创建插件-android:https://blog.csdn.net/u014284625/article/details/79922677
    6. apache-cordova官方文档:https://cordova.apache.org/docs/en/latest/
    7. 创建并调试Cordova插件:https://www.outsystems.com/blog/posts/how-to-create-a-cordova-plugin-from-scratch/
    8. 如何测试插件:https://kerrishotts.github.io/pgday/workshops/2017/campp/testing.html

    相关文章

      网友评论

        本文标题:Cordova开发指南

        本文链接:https://www.haomeiwen.com/subject/xzopkqtx.html