八、uni-app 原生插件開發(fā)04 - 開發(fā)原生插件

至此,我們完成了插件的使用,整個(gè)過程我們都是在 HBuilder X 中進(jìn)行,接下來我們進(jìn)入開發(fā)插件階段。

概述

uni-app原生插件是基于開源項(xiàng)目 weex0.26.0 版本架構(gòu)的擴(kuò)展機(jī)制,同樣支持Module(非UI控件)Component(原生UI控件)兩種擴(kuò)展類型,因此可以非常方便的將weex擴(kuò)展插件移植到uni-app原生插件中。 在uni-app中支持vue和nvue兩種頁面,vue頁面是基于小程序引擎渲染,nvue頁面是基于weex引擎渲染。

  • vue頁面中僅支持使用Module類型uni-app原生插件,不支持調(diào)用同步方法返回?cái)?shù)據(jù)

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

參考下面兩個(gè)個(gè)官方文檔,完成基礎(chǔ)的開發(fā)環(huán)境準(zhǔn)備:

環(huán)境準(zhǔn)備

iOS uni-app原生插件開發(fā)文檔 1.2 文檔如下:

在您閱讀此文檔時(shí),首先要知道 uni-app 支持 weex 插件,同時(shí)我們假定您已經(jīng)具備了相應(yīng) iOS 應(yīng)用開發(fā)經(jīng)驗(yàn),學(xué)習(xí)過 weex 知識(shí)并能夠理解相關(guān)概念。此外,您也應(yīng)該對 HTML , JavaScript , CSS 等有一定的了解,并且熟悉在JavaScript 和 Objective-C 環(huán)境下的 JSON 格式數(shù)據(jù)操作等。

開發(fā)前準(zhǔn)備:

  • OS X 10.14.0+
  • Xcode 11.0+
  • 下載開發(fā)插件需要的 SDK 包 最新版本的SDK包,找到里面的 HBuilder-uniPluginDemo 文件夾,里面包含 HBuilder-uniPlugin 插件開發(fā)工程,后面會(huì)用到( 本文使用 iOSSDK@2.4.6.71959_20191210 )
  • 下載開發(fā)插件時(shí)會(huì)用到的 js 代碼的開發(fā)工具 HBuilderX(下載地址),下載哪個(gè)版本的 HBuilderX 需要注意下,保持和上條中提到的 SDK 包(在下載 SDK 包的下載界面中有版本相關(guān)的文字描述如下圖),它提到的版本號(hào)一致(HBuilderX 版本 2.5.1.20200103 )
  • 確定 SDK 包里的 Xcode 工程 HBuilder-uniPlugin 內(nèi)是否引用了 SDK 包里的 liblibWeex.a 庫和 weex-main-jsfm.js 文件
  • 更新 uni-app 離線打包支持,需要使用 HBuilderX (2.4.6.20191210) 版本生成本地打包 APP 資源

在官方文檔中,講到需要我們 學(xué)習(xí) weex 0.26.0 版本框架 API,本文檔中可以省略掉,和 weex 相關(guān)的細(xì)節(jié)后面會(huì)講到,不用系統(tǒng)去學(xué)習(xí)。

插件開發(fā)過程梳理(個(gè)人認(rèn)為很重要,但是官方文檔里面沒有)

最新版本的 SDK 是個(gè)什么東西?

從官方提供的鏈接下載 SDK,下載之后解壓出來是這么一個(gè)文件夾 ,iOSSDK@2.4.6.71959_20191210,命令中包含了版本號(hào)和 release 日期,我們打開看一下其中內(nèi)容。

image.png

開發(fā)原生插件,我們只需要關(guān)注 HBuilder-uniPluginDemo 這個(gè)文件夾即可,其余的先不管。

HBuilder-uniPluginDemo 文件夾中包含的是一個(gè) xcode 工程,打開工程,我們發(fā)現(xiàn)其結(jié)構(gòu)如下。


image.png

這張圖 hin 重要,這張圖從終端視角,展示了 uni-app 是怎樣跑起來的。展示了我們寫的 js 代碼和我們 原生插件是如何產(chǎn)生聯(lián)系的。

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

image.png

有了這個(gè)前置知識(shí)之后,我們再畫個(gè)圖,從 APP 這個(gè)宏觀角度來理解一下 uni-app 開發(fā)原生插件開發(fā) 這兩個(gè)過程。

image.png

uni-app 開發(fā) 就是在 HBuilder 中用 js 寫頁面和邏輯,原生插件以 framework 的方式提供,在 js 中按照某種規(guī)范引用(前面的文章中,有講到如何引用插件市場的原生插件,今天開發(fā)調(diào)試的時(shí)候,我們會(huì)講如何引用本地插件)。

原生插件開發(fā) 就是在 xcode 中用 oc 寫 framework,調(diào)試 framework 的時(shí)候,我們使用 www 文件下的資源模擬 js 調(diào)用。

uni-app原生插件開發(fā)(xcode 側(cè))

iOS平臺(tái)uni-app原生插件開發(fā)文檔 文檔中介紹的是制作 .a 靜態(tài)庫,本文制作的是一個(gè) .framework 靜態(tài)庫,接下來主要介紹如何在 uni-app 中基于 WeexSDK 開發(fā) iOS 原生插件。

制作 framework

新建一個(gè) framework 項(xiàng)目。

新建 framework 工程并進(jìn)行相關(guān)配置

新建一個(gè)名稱為 WBOCRUniSDK 的 framework 工程,xcode11 中,默認(rèn)創(chuàng)建的是一個(gè)動(dòng)態(tài)庫,我們將其改為靜態(tài)庫。

image.png

在下載的工程包 iOSSDK@2.4.6.71959_20191210 里找到 HBuilder-uniPluginDemo 文件夾,然后打開 HBuilder-uniPlugin工程,把剛創(chuàng)建的靜態(tài)庫工程引入到 HBuilder-uniPlugin 工程。

image.png

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

image.png

然后,在靜態(tài)庫工程 WBWeexOCRSDK 的 Header Search Paths 中添加引用 "$(SRCROOT)/../../SDK/inc" ,做這一步的目的,就是為了引入 weex SDK的一些依賴(注意:后面要選擇 recursive,否則會(huì)報(bào) 'WXModuleProtocol.h' file not found 的錯(cuò)誤!)
。
如下圖所示:

image.png

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

image.png

配置需要注冊的插件

打開 HBuilder-uniPlugin 工程里的 info.plist 文件 加入節(jié)點(diǎn),需要嚴(yán)格按要求配置,如下圖所示:

image.png

其中,hooksClass 的值是類名,是給有些插件需要在 app 啟動(dòng)時(shí)做初始化或者獲取系統(tǒng)事件用的,如果沒有可以不填為空;
plugins 下的每一項(xiàng)是 weex 擴(kuò)展模塊或組件能力相關(guān)的配置信息,里面包含name(填weex模塊或組件類名對應(yīng)的js層用到的字符串, js層中將通過該字符串來使用原生層的模塊或組件),class(填weex模塊或組件類名),type(填modulecomponent,一定不能配置錯(cuò)),注意不支持 weex 的 handler 擴(kuò)展。

至此,xcode 側(cè)的配置就完成了。

uni-app原生插件開發(fā)(HBuilder 側(cè))

我們在 uni-app 中寫一個(gè)頁面,頁面上有調(diào)用原生 SDK 的方法。

具體一點(diǎn),如下圖所示:

image.png

我在 HBuilder 中,寫一個(gè)頁面頁面上有三個(gè)按鈕,分別調(diào)起三個(gè)原生接口(獲取簽名、啟動(dòng) OCR 、和啟動(dòng)刷臉),底部展示原生接口的回調(diào)信息,默認(rèn)展示"Result"。

寫 UI 和調(diào)用原生接口的代碼,都在 index.vue 中編寫。

我先寫一個(gè)包含 三個(gè) 按鈕的的 頁面,并且給三個(gè)按鈕分別設(shè)置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">啟動(dòng) OCR</button>
        <button class="button" @click="face">啟動(dòng) 刷臉</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>

接下來,需要在按鈕點(diǎn)擊之后調(diào)起 原生插件。在上面 xcode 配置中,我即將開發(fā)的原生插件命名為 WB-OCRSDK,所以引用插件的方法為:

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

引用插件之后,我需要調(diào)用獲取簽名、OCR 和 刷臉三個(gè)方法,目前在 xcode 中還沒有開發(fā),我預(yù)先給他們命名:

getWBSign() {
  // 獲取簽名
  ocr.getDebugParam({
    appId: xxx,
    orderNO: xxx,
  }, result => {
    console.log("【uni log】getDebugParam callback ================> result.");
    console.log(result);
  });
  
},
ocr() {
    // 啟動(dòng) 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() {
  // 啟動(dòng) 刷臉
  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);
  });

我在插件中必須實(shí)現(xiàn)一個(gè) getDebugParam:callback:方法,js 傳遞參數(shù)給原生代碼,原生代碼提供一個(gè)回調(diào) callback,將結(jié)果回傳給 js。

其余兩個(gè)接口套路一樣。

至此,js 端的接口寫好,我們把 js 打包成資源文件,然后將其復(fù)制到 xcode 項(xiàng)目下的 www 文件夾下去。

js 代碼如何調(diào)用 framework

按照官方文檔,新建一個(gè) WBOCRSDKModule 類。

image.png

在 .m 中添加 WX_EXPORT_METHOD 代碼,添加完成之后,js 就可以透過 weex 來調(diào)用我們原生代碼了。

實(shí)現(xiàn)這幾個(gè)方法。

@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
{
  /// 模擬拉取簽名地址,合作方接入時(shí),找自己后臺(tái)拉取
}
- (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 調(diào)用 oc 的流程,接下來需要做的事兒就是填充業(yè)務(wù)代碼了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容