美文网首页
八、uni-app 原生插件开发04 - 开发原生插件

八、uni-app 原生插件开发04 - 开发原生插件

作者: TankXie | 来源:发表于2020-01-16 13:35 被阅读0次

    至此,我们完成了插件的使用,整个过程我们都是在 HBuilder X 中进行,接下来我们进入开发插件阶段。

    概述

    uni-app原生插件是基于开源项目 weex0.26.0 版本架构的扩展机制,同样支持Module(非UI控件)Component(原生UI控件)两种扩展类型,因此可以非常方便的将weex扩展插件移植到uni-app原生插件中。 在uni-app中支持vue和nvue两种页面,vue页面是基于小程序引擎渲染,nvue页面是基于weex引擎渲染。

    • vue页面中仅支持使用Module类型uni-app原生插件,不支持调用同步方法返回数据

    • nvue页面中支持使用Module和Component类型uni-app原生插件

    参考下面两个个官方文档,完成基础的开发环境准备:

    环境准备

    iOS uni-app原生插件开发文档 1.2 文档如下:

    在您阅读此文档时,首先要知道 uni-app 支持 weex 插件,同时我们假定您已经具备了相应 iOS 应用开发经验,学习过 weex 知识并能够理解相关概念。此外,您也应该对 HTML , JavaScript , CSS 等有一定的了解,并且熟悉在JavaScript 和 Objective-C 环境下的 JSON 格式数据操作等。

    开发前准备:

    • OS X 10.14.0+
    • Xcode 11.0+
    • 下载开发插件需要的 SDK 包 最新版本的SDK包,找到里面的 HBuilder-uniPluginDemo 文件夹,里面包含 HBuilder-uniPlugin 插件开发工程,后面会用到( 本文使用 iOSSDK@2.4.6.71959_20191210 )
    • 下载开发插件时会用到的 js 代码的开发工具 HBuilderX(下载地址),下载哪个版本的 HBuilderX 需要注意下,保持和上条中提到的 SDK 包(在下载 SDK 包的下载界面中有版本相关的文字描述如下图),它提到的版本号一致(HBuilderX 版本 2.5.1.20200103 )
    • 确定 SDK 包里的 Xcode 工程 HBuilder-uniPlugin 内是否引用了 SDK 包里的 liblibWeex.a 库和 weex-main-jsfm.js 文件
    • 更新 uni-app 离线打包支持,需要使用 HBuilderX (2.4.6.20191210) 版本生成本地打包 APP 资源

    在官方文档中,讲到需要我们 学习 weex 0.26.0 版本框架 API,本文档中可以省略掉,和 weex 相关的细节后面会讲到,不用系统去学习。

    插件开发过程梳理(个人认为很重要,但是官方文档里面没有)

    最新版本的 SDK 是个什么东西?

    从官方提供的链接下载 SDK,下载之后解压出来是这么一个文件夹 ,iOSSDK@2.4.6.71959_20191210,命令中包含了版本号和 release 日期,我们打开看一下其中内容。

    image.png

    开发原生插件,我们只需要关注 HBuilder-uniPluginDemo 这个文件夹即可,其余的先不管。

    HBuilder-uniPluginDemo 文件夹中包含的是一个 xcode 工程,打开工程,我们发现其结构如下。


    image.png

    这张图 hin 重要,这张图从终端视角,展示了 uni-app 是怎样跑起来的。展示了我们写的 js 代码和我们 原生插件是如何产生联系的。

    其中,www 文件夹下的资源,是在 HBuilder 中打包生成的,打包入口如下。

    image.png
    有了这个前置知识之后,我们再画个图,从 APP 这个宏观角度来理解一下 uni-app 开发原生插件开发 这两个过程。 image.png
    uni-app 开发 就是在 HBuilder 中用 js 写页面和逻辑,原生插件以 framework 的方式提供,在 js 中按照某种规范引用(前面的文章中,有讲到如何引用插件市场的原生插件,今天开发调试的时候,我们会讲如何引用本地插件)。

    原生插件开发 就是在 xcode 中用 oc 写 framework,调试 framework 的时候,我们使用 www 文件下的资源模拟 js 调用。

    uni-app原生插件开发(xcode 侧)

    iOS平台uni-app原生插件开发文档 文档中介绍的是制作 .a 静态库,本文制作的是一个 .framework 静态库,接下来主要介绍如何在 uni-app 中基于 WeexSDK 开发 iOS 原生插件。

    制作 framework

    新建一个 framework 项目。

    新建 framework 工程并进行相关配置

    新建一个名称为 WBOCRUniSDK 的 framework 工程,xcode11 中,默认创建的是一个动态库,我们将其改为静态库。

    image.png
    在下载的工程包 iOSSDK@2.4.6.71959_20191210 里找到 HBuilder-uniPluginDemo 文件夹,然后打开 HBuilder-uniPlugin工程,把刚创建的静态库工程引入到 HBuilder-uniPlugin 工程。 image.png

    SDK 支持的最低 iOS 版本为 iOS 9.0,修改 iOS Deployment Target 为 9.0。

    image.png

    然后,在静态库工程 WBWeexOCRSDK 的 Header Search Paths 中添加引用 "$(SRCROOT)/../../SDK/inc" ,做这一步的目的,就是为了引入 weex SDK的一些依赖(注意:后面要选择 recursive,否则会报 'WXModuleProtocol.h' file not found 的错误!)

    如下图所示:

    image.png

    然后,在 HBuilder-uniPlugin 工程的Link Binary With Libraries中添加 WBWeexOCRSDK.framework 库;然后,在 Target Dependencies 中,添加插件工程的 WBWeexOCRSDK 的 targets,如下图所示:

    image.png

    配置需要注册的插件

    打开 HBuilder-uniPlugin 工程里的 info.plist 文件 加入节点,需要严格按要求配置,如下图所示:

    image.png
    其中,hooksClass 的值是类名,是给有些插件需要在 app 启动时做初始化或者获取系统事件用的,如果没有可以不填为空;
    plugins 下的每一项是 weex 扩展模块或组件能力相关的配置信息,里面包含name(填weex模块或组件类名对应的js层用到的字符串, js层中将通过该字符串来使用原生层的模块或组件),class(填weex模块或组件类名),type(填modulecomponent,一定不能配置错),注意不支持 weex 的 handler 扩展。

    至此,xcode 侧的配置就完成了。

    uni-app原生插件开发(HBuilder 侧)

    我们在 uni-app 中写一个页面,页面上有调用原生 SDK 的方法。

    具体一点,如下图所示:

    image.png

    我在 HBuilder 中,写一个页面页面上有三个按钮,分别调起三个原生接口(获取签名、启动 OCR 、和启动刷脸),底部展示原生接口的回调信息,默认展示"Result"。

    写 UI 和调用原生接口的代码,都在 index.vue 中编写。

    我先写一个包含 三个 按钮的的 页面,并且给三个按钮分别设置click 方法。

    <template>
        <view class="content">
            <image class="logo" src="/static/logo.png"></image>
            <view class="text-area">
                <text class="title">{{title}}</text>
            </view>
            <button class="button" @click="getWBSign">获取 OCR 签名</button>
            <button class="button" @click="ocr">启动 OCR</button>
            <button class="button" @click="face">启动 刷脸</button>
            <text class="result">{{result}}</text>
    
        </view>
    </template>
    <style>
        .content {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
        }
        .logo {
            height: 200rpx;
            width: 200rpx;
            margin-top: 200rpx;
            margin-left: auto;
            margin-right: auto;
            margin-bottom: 50rpx;
        }
    
        .text-area {
            display: flex;
            justify-content: center;
        }
    
        .title {
            font-size: 36rpx;
            color: #8f8f94;
        }
    
        .button {
            display: flex;
            justify-content: center;
        }
        .result {
            margin-left: auto;
            margin-right: auto;
            font-size: 22rpx;
        }
    </style>
    

    接下来,需要在按钮点击之后调起 原生插件。在上面 xcode 配置中,我即将开发的原生插件命名为 WB-OCRSDK,所以引用插件的方法为:

    const plugin = uni.requireNativePlugin('WB-OCRSDK');
    

    引用插件之后,我需要调用获取签名、OCR 和 刷脸三个方法,目前在 xcode 中还没有开发,我预先给他们命名:

    getWBSign() {
      // 获取签名
      ocr.getDebugParam({
        appId: xxx,
        orderNO: xxx,
      }, result => {
        console.log("【uni log】getDebugParam callback ================> result.");
        console.log(result);
      });
      
    },
    ocr() {
        // 启动 OCR
      ocr.startOCR({
        version : xxxx,
        appId : xxxx,
        nonce : xxxx,
        userId : xxxx,
        sign : xxxx,
        orderNo : xxxx,
        config: {
          "SDKType": 2,
          "needBothSidesRecognized":true
        }
      }, result => {
        console.log("【uni log】startOCR callback ================> result.");
      });
    },
      
    face() {
      // 启动 刷脸
      ocr.startFace({
        version : xxx,
        appId : xxx,
        nonce : xxx,
        userId : xxx,
        sign : xxx,
        orderNo : xxx
      }, result => {
        console.log("【uni log】startFace callback ================> result.");
      });
    
    }
    

    以获取签名为例,来说明。

      ocr.getDebugParam({
        appId: xxx,
        orderNO: xxx,
      }, result => {
        console.log("【uni log】getDebugParam callback ================> result.");
        console.log(result);
      });
    

    我在插件中必须实现一个 getDebugParam:callback:方法,js 传递参数给原生代码,原生代码提供一个回调 callback,将结果回传给 js。

    其余两个接口套路一样。

    至此,js 端的接口写好,我们把 js 打包成资源文件,然后将其复制到 xcode 项目下的 www 文件夹下去。

    js 代码如何调用 framework

    按照官方文档,新建一个 WBOCRSDKModule 类。

    image.png
    在 .m 中添加 WX_EXPORT_METHOD 代码,添加完成之后,js 就可以透过 weex 来调用我们原生代码了。

    实现这几个方法。

    @implementation WBOCRSDKModule
    WX_EXPORT_METHOD(@selector(startFace:callback:))
    WX_EXPORT_METHOD(@selector(startOCR:callback:))
    WX_EXPORT_METHOD(@selector(getDebugParam:callback:))
    #pragma mark - Export Method
    - (void)getDebugParam:(NSDictionary *)options callback:(WXModuleCallback)callback
    {
      /// 模拟拉取签名地址,合作方接入时,找自己后台拉取
    }
    - (void)startOCR:(NSDictionary *)options callback:(WXModuleCallback)callback
    {
        NSLog(@"%s",__func__);
        NSLog(@"%@",options);
    }
    - (void)startFace:(NSDictionary *)options callback:(WXModuleCallback)callback
    {
        NSLog(@"%s",__func__);
        NSLog(@"%@",options);
    }
    @end
      
    

    至此,走通了 js 调用 oc 的流程,接下来需要做的事儿就是填充业务代码了。

    相关文章

      网友评论

          本文标题:八、uni-app 原生插件开发04 - 开发原生插件

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