iOS uni-app原生插件制作

照着文档和Demo挺顺利就调通了的。记录下制作和调用过程。

阅读提示:

1.本文章仅为iOS原生插件制作,无Android部分。

2.面向有iOS开发基础的读者。

3.我就是参照官方文档做的,如果按照官方文档能直接做好就不用继续看了。

4.操作顺序和官方文档有几处不同,但不会影响最终结果。


uni-app官方文档:uni-app原生插件(native plugin)开发指南

uni-app iOS端官方文档:iOS uni-app原生插件开发文档 

(官方Demo在文档中有写,本文是以官方Demo中的uni-app工程为基础的)


共5步,每一步都有很详细的图文讲解。

第一步:准备工作。

第二步:创建iOS原生静态库工程

第三步:把静态库工程添加到uni-app项目中并进行相关配置

第四步:开发桥接类

第五步:使用HBuilder新建uni-app项目调用插件。



第一步:准备。

官方文档

按照官方文档提示,下载好最新版本的SDK包(里面会有uni-app的工程Demo)以及HBuilderX开发工具。这两个就够。


第二步:创建iOS原生静态库。.a或.framework都可以。官方文档中也给了两个参考链接,我直接搬过来。

iOS如何制作.a库

iOS如何制作.framework库

这里由于我有界面以及资源文件,所以我习惯选择.framework。还是讲下具体步骤……(我也是根据文章里的步骤一步一步做的,会做的可以跳过不看)

2.1 创建命名为WeexVinOCR的工程后,删掉工程同名.h文件(创建项目自带的),删除后目录如下图所示。

framework项目目录

2.2 添加所需文件,把插件实现功能所需的原生类全部拖入。(资源文件不拖,是集成到uni-app后放在uni-app项目里的)拖入时请选择以下三个选项。

拖入选项

2.3 创建一个桥接类继承NSObject,最好命名为XXXModule。(命名规范,取其他的也不会影响,但要记住这个桥接类的名字,后面的步骤要配置的)创建完毕目录如下:(提一句,静态库是可以包含静态库的,我但我只尝试过.framework包含.a和.a包含.a这两种情况)

创建好Module类

2.4 接下来是一些framework工程常规设置

(1)TARGETS -> Build Settings -> Build Active Architecture Only 设置为NO,意思是当前打包的.framework支持所有的设备,否则打包时只能用当前版本的模拟器或真机运行。

Build Active Architecture Only设置为NO

(2)这里设置最低支持系统

设置最低支持系统

(3)设置编译release包

Edit Scheme
选择release

(4)Command + B编译,看看是否能编译通。我这边报错是因为用到了一些系统库,把他们添加到项目里就行。

报错

添加了相关依赖就好了。

添加依赖库就可以编译成功了

第三步:把.framework工程添加到uni-app工程中,并配置好。

3.1 在Finder中找到.framework工程文件夹和uni-app工程文件夹(我用的是官网下载的Demo)

.framework项目拷贝

3.2 打开uni-app项目,把.framework工程添加到项目中。

右键 选择AddFiles

选择.framework的xcodeproj文件,点击Add

选择xcodeproj文件

3.3 在Targets -> General -> Frameworks,Libraries,and Embedded Content添加依赖

添加依赖

3.4 可以将插件用到的资源文件拖入项目,请注意是拖入uni-app工程中,而不是.framework工程中(否则我不确定运行的时候能不能正常使用)。资源文件拖入请务必勾选Add to target(否则运行的时候肯定不能正常使用)

资源文件拖入位置
拖入时勾选

3.5 在uni-app项目中注册插件,首先贴上文档的说明

文档中这一步的说明

按照文档的说明,我的插件应该是这样配置的。注意,格式以及层次请严格按照图中配置。

配置详情

(1)hooksClass是类名,这个类是在APP启东市做初始化或者获取系统时间用的,由于我的插件没有用到,所以hooksClass为空。(有这方面需求的需要根据官方文档创建这个类并且进行一系列的相关配置!!我的文章里没有这部分内容,请注意!

(2)class是.framework中的桥接类的类名(就是之前创建的XXXModule类)

(3)name和class写一样的就行了省事。(但要记住这个字符串,之后js要用到)

3.6 TARGETS -> Build Settings -> Header Search Paths 添加 "$(SRCROOT)/../../SDK/inc" 并设置为recursive。

这个是桥接类开发时用到的头文件的路径,具体因项目而异,官方Demo直接这么配置就行。

Header Search Paths配置
项目位置以及头文件位置示例

第四步:开发桥接类。

4.1 首先在桥接类.h中添加如下图所示代码,然后编译。

桥接类头文件示例

这里我第一次开发的时候遇到了报错找不到WXModuleProtocol.h,最后发现竟然是因为我把Demo单独放在了一个地方,编译器就找不到那个头文件了……尽管最后我把那个头文件夹也复制到了对应的地方,也尝试修改相对路径,都行不通。最后还是把Demo放回原处运行才成功的。╮(╯▽╰)╭

如果你也报错找不到头文件的话,那就再次确定下步骤3.6配置的路径是否能找到对应的头文件吧。

4.2 在4.1编译通过的情况下,修改桥接类.m文件如下图所示。

.m代码示例

简而言之:

(1)把需要暴露给JS调用的方法通过WX_EXPORT_METHOD()宏定义声明一下

(2)如果想要在不同的方法中使用同一个对象(比如callback回调),可以写作成员变量。(这是iOS的知识啦)

(3)如果想弹出控制器怎么办呢。我怎么获取当前的控制器?官方文档底部(我直接粘贴在文章里,懒癌患者福音)

// 获取当前显示的 UIViewController

+ (UIViewController *)dc_findCurrentShowingViewController {

    //获得当前活动窗口的根视图

    UIViewController *vc = [UIApplication sharedApplication].keyWindow.rootViewController;

    UIViewController *currentShowingVC = [self findCurrentShowingViewControllerFrom:vc];

    return currentShowingVC;

}

+ (UIViewController *)findCurrentShowingViewControllerFrom:(UIViewController *)vc {

    // 递归方法 Recursive method

    UIViewController* currentShowingVC;

    if ([vc presentedViewController]) {

        // 当前视图是被presented出来的

        UIViewController* nextRootVC = [vc presentedViewController];

        currentShowingVC = [self findCurrentShowingViewControllerFrom:nextRootVC];

    } else if([vc isKindOfClass:[UITabBarController class]]) {

        // 根视图为UITabBarController

        UIViewController *nextRootVC = [(UITabBarController *)vc selectedViewController];

        currentShowingVC = [self findCurrentShowingViewControllerFrom:nextRootVC];

    } else if ([vc isKindOfClass:[UINavigationController class]]) {

        // 根视图为UINavigationController

        UIViewController *nextRootVC = [(UINavigationController *)vc visibleViewController];

        currentShowingVC = [self findCurrentShowingViewControllerFrom:nextRootVC];

    } else {

        // 根视图为非导航类

        currentShowingVC = vc;

    }

    return currentShowingVC;

}


第五步:使用HBuilder新建uni-app项目调用插件。(由于没有uni-app和js开发经验,此处只使用最简单直观的方式)

5.1 打开HBuilder,新建uni-app项目,我命名为Uni-VinUniPlugin

新建uni-app项目

5.2 编写JS代码,在index.vue内写如下代码(图后有文字版可以直接复制)。下图所示代码的意思就是界面上有一个按钮,按钮的点击事件调用原生的接口实现功能,然后原生返回数据给JS。

JS代码示例

<template>

<view class="content">

<button type="default" :value="value" @click="clickBtn" >我是按钮</button>

</view>

</template>

<script>

const modal = uni.requireNativePlugin('modal');

const vinModule = uni.requireNativePlugin('VinOCRModule');

export default {

data() {

},

onLoad() {

},

methods: {

clickBtn() {

vinModule.show({

position: 'start',

content: "测试文字没啥用",

}, result => {

const msg = JSON.stringify(result);

console.log(msg);

modal.toast({

message: msg,

duration: 1.5

});

});

},

}

}

</script>

<style>

.content {

display: flex;

flex-direction: column;

align-items: center;

justify-content: center;

}

</style>

5.3 打包

打包操作

打包好的代码如下图所示,把它拷贝到到HBuilder-uniPlugin工程的Pandora目录下的apps目录下,注意这个生成的文件夹名(官方叫appid),后面要用到

生成的文件以及拷贝的位置

5.4 control.xml里的appid和生成的文件夹名称要改成一样的

control.xml的appid和生成的文件夹名要一致

大功告成,运行!界面如下:

界面

原生的回调:

官方提示:调试过程中遇到问题:

(1)如果是原生的问题,直接修改原生代码运行就可以了。

(2)如果是js代码的问题,需要修改.nvue或.vue的代码,然后需要重新导出编译后的代码(编译导出代码有可能会报错,注意控制台的日志信息,千万不要把有问题的资源拿去调试),重新将新生成的文件夹拷贝到HBuilder-uniPlugin工程的Pandora文件夹内对应的目录下(直接替换www文件就行,appid不会变),然后务必删除之前的app,再重新运行工程。


2020.3.18补充: HBuilder点击发布的时候提示我要选择微信开发者工具安装目录。我已经安装了微信开发者工具,但是它还是提示请选择正确的路径。原因是前些天我刚更新最新的开发者工具。我的解决办法是去下载个旧版的微信开发者工具。估计HBuilder新版就没这个问题了。

另提示:我的插件无需在app启动时初始化或者获取系统事件,所以没有进行任何这方面的开发和配置。有这部分需求的读者需要自行去官网查漏补缺。(先进行OC和JS的互调,再进行这部分的补充是没啥影响的)

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

推荐阅读更多精彩内容

  • 至此,我们完成了插件的使用,整个过程我们都是在 HBuilder X 中进行,接下来我们进入开发插件阶段。 概述 ...
    TankXie阅读 4,074评论 4 6
  • 公司新产品要求发布到各家小程序,最近研究对比了社区主流的几家小程序开发框架,独坑不如拉人众坑,分享给各位,欢迎和我...
    jianfly阅读 63,513评论 23 97
  • 先说说兴趣是什么?根据百度百科的解释,总结为“兴趣以需要为基础,兴趣是精神需要。人因为兴趣而热爱一件事物,并探索其...
    崇德先生阅读 2,451评论 2 5
  • 上车翻翻微博,就过了一半路了,向车窗外看看,发现已经到了之前的公司,上次你送我回来的地方,清晨的阳光有点虚弱,可能...
    某某是个状态阅读 130评论 0 0
  • 见到一枚枯叶,如同望着你的将来。 失了笑容的脸颊,呢喃不休, 琐屑,教唆着你的疲惫。 黑色燕尾蝶,寻找各自栖身的处...
    小曼的岛阅读 1,039评论 24 38