uniapp原生插件开发(iOS)

开发环境

  • iOS开发环境,Xcode 12.1 及以上版本
  • 下载开发插件需要的 SDK包 并解压
  • 安装 uni-app 开发工具 HBuilderX

1、创建插件工程

打开 Xcode,创建一个新的Framework工程,然后点击 Next


image.png

输入插件工程名称(建议使用一个性化的前缀,避免与其他人的插件包名冲突),其他项不需要修改保持工程默认填充的即可,然后点击Next


image.png

然后选择工程存放路径,直接存放在 iOSSDK目录中的 HBuilder-uniPluginDemo 插件开发主工程目录下,然后点击 Create
image.png

然后选中工程名,在TARGETS->Build Settings中,将 Mach-O Type 设置为 Static Library 如下图所示


image.png

2、导入插件工程

打开 iOSSDK/HBuilder-uniPluginDemo工程目录,双击目录中的HBuilder-uniPlugin.xcodeproj 文件运行插件开发主工程
在 Xcode 项目左侧目录选中主工程名,然后点击右键选择Add Files to “HBuilder-uniPlugin” ...


image.png

然后选择您刚刚创建的插件工程路径中,选中插件工程文件,勾选 Create folder references 和 Add to targets 两项,然后点击Add


image.png

3、工程配置

然后在 Xcode 项目左侧目录选中主工程名,在TARGETS->Build Phases->Dependencies中点击+


image.png

在弹窗中选中插件工程,如图所示,然后点击Add,将插件工程添加到Dependencies中


image.png

然后在Link Binary With Libraries中点击+,同样在弹窗中选中插件工程,点击Add
image.png

此时可以看到 Dependencies 和 Link Binary With Libraries 都添加了插件工程,如下图所示


image.png

接下来需要在插件工程的Header Search Paths中添加开发插件所需的头文件引用,头文件存放在主工程的HBuilder-Hello/inc中,添加方法如下图所示,在 Xcode 项目左侧目录选中插件工程名,找到TARGETS->Build Settings->Header Search Paths双击右侧区域打开添加窗口,然后将inc目录拖入会自动填充相对路径,然后将模式改成recursive

4、代码实现

插件扩展方式

扩展原生功能有两种方式:
module:不需要参与页面布局,只需要通过 API 调用原生功能,比如:获取当前定位信息、数据请求等功能,通过扩展module的方式来实现;
component:需要参与页面布局,比如:map、image等需要显示UI的功能,通过扩展component即组件的方法来实现;

扩展 module

新建TestModule类,继承 DCUniModule,引入 DCUniModule.h 头文件。
然后在 TestModule.m 文件中添加实现方法


/// 异步方法(注:异步方法会在主线程(UI线程)执行)
/// @param options js 端调用方法时传递的参数   支持:String、Number、Boolean、JsonObject 类型
/// @param callback 回调方法,回传参数给 js 端   支持: NSString、NSDictionary(只能包含基本数据类型)、NSNumber 类型
- (void)testAsyncFunc:(NSDictionary *)options callback:(UniModuleKeepAliveCallback)callback {
 
    // options 为 js 端调用此方法时传递的参数 NSLog(@"%@",options); // 可以在该方法中实现原生能力,然后通过 callback 回调到 js
 
   if (callback) {
       // 第一个参数为回传给js端的数据,第二个参数为标识,表示该回调方法是否支持多次调用,如果原生端需要多次回调js端则第二个参数传 YES;
        callback(@"success",NO);
 
    }
}
//通过宏 UNI_EXPORT_METHOD 将异步方法暴露给 js 端,只有通过UNI_EXPORT_METHOD暴露的原生方法才能被 js 端识别到
UNI_EXPORT_METHOD_SYNC(@selector(testSyncFunc:))
5、配置插件信息

选中工程中的HBuilder-uniPlugin-Info.plist文件右键->Open As->Source Code找到dcloud_uniplugins节点,copy下面的内容添加到dcloud_uniplugins节点下,按插件的实际信息填写对应的项

<dict>
    <key>hooksClass</key>
    <string>填写 hooksClass 类名 </string>
    <key>plugins</key>
    <array>
        <dict>
            <key>class</key>
            <string>填写 module 或 component 的类名</string>
            <key>name</key>
            <string>填写暴露给js端对应的 module 或 component 名称</string>
            <key>type</key>
            <string>填写 module 或 component</string>
        </dict>
    </array>
</dict>

在 uni-app 项目中调用 module 方法

<template>
    <div>
        <button type="primary" @click="testAsyncFunc">testAsyncFunc</button>
        <button type="primary" @click="testSyncFunc">testSyncFunc</button>
    </div>
</template>
 
<script>
    // 首先需要通过 uni.requireNativePlugin("ModuleName") 获取 module
    var testModule = uni.requireNativePlugin("DCTestUniPlugin-TestModule")
    export default {
        methods: {
            testAsyncFunc() {
                // 调用异步方法
                testModule.testAsyncFunc({
                        'name': 'uni-app',
                        'age': 1
                    },
                    (ret) => {
                        uni.showToast({
                            title:'调用异步方法 ' + ret,
                            icon: "none"
                        })
                    })
            },
            testSyncFunc() {
                // 调用同步方法
                var ret = testModule.testSyncFunc({
                    'name': 'uni-app',
                    'age': 1
                })
 
                uni.showToast({
                    title:'调用同步方法 ' + ret,
                    icon: "none"
                })
            }
        }
    }
</script>
6、导入 uni-app 资源

生成 uni-app 本地打包资源
首先需要生成本地打包资源,在 HBuilderX 中选您的 uni-app 工程,右键->发现->原生App-本地打→生成本地打包App资源


image.png

项目编译完成后会在 HBuilderX 控制台输出资源存路径,点击路径会自动打开资源所在文件夹


image.png

导入 uni-app 资源

接下来,将应用资源导入到插件开发主工程的HBuilder-Hello/Pandora/apps/中,如下图所示,直接拖进去即可

image.png

然后打开工程的 control.xml 文件,将 appid 改成 uni-app项目的 id,如下图所示
image.png

然后运行项目测试,如下图所示(能调到 module 的方法,并且可以获取 module 返回的数据,则说明功能正常)
image.png

7、 生成插件包

编译生成插件库文件(.framework 或 .a)

如下图所示,将编译工程选择为插件项目(DCTestUniPlugin),运行设备选择Generic iOS Device

image.png

然后点击Edit Scheme...在弹窗中,将Run->Info->Build Configuration切换到Release,然后点击Close关闭弹窗
然后在 Xcode 左侧目录中选中插件工程名,查看TARGETS->Build Settings->Architectures,确保

  • Build Active Architecture Only->ReleaseNo
  • Valid Architectures 中至少包含 arm64armv7(一般保持工程默认配置即可)
    image.png

    然后点击运行按钮Command + B 编译运行工程
    编译完成后,在插件工程 Products 下生成的库(DCTestUniPlugin.framework)即为插件所需要的依赖库文件,右键->Show in Finder,可打开库所在文件夹
    image.png

8、 编写 package.json 配置文件

package.json 为插件的配置文件,配置了插件id、格式、插件资源以及插件所需权限等等信息

新建一个 package.json 文件,根据插件实际情况填写插件配置信息

{
    "name": "TestUniPlugin",
    "id": "DCTestUniPlugin",
    "version": "1.0.0",
    "description": "uni示例插件",
    "_dp_type": "nativeplugin",
    "_dp_nativeplugin": {
        "ios": {
            "plugins": [{
                "type": "module",
                "name": "DCTestUniPlugin-TestModule",
                "class": "TestModule"
            }, {
                "type": "component",
                "name": "dc-testmap",
                "class": "TestComponent"
            }],
            "frameworks": ["MapKit.framework"],
            "integrateType": "framework",
            "deploymentTarget": "9.0"
        }
    }
}

然后以插件id为名新建一个文件夹,将编辑好的 package.json 放进去,然后在文件夹中在新建一个 ios (小写)文件夹,将刚刚生成的依赖库(DCTestUniPlugin.framework)copy 到 ios 根目录,这样我们的插件包就构建完成了,如下图所示


image.png

9、使用插件

HBuilderX 的 uni-app 项目创建中“nativeplugins”目录(如不存在则创建)将插件配置到uni-app项目下的“nativeplugins”目录


image.png

uni-app原生插件本地配置
将原生插件配置到uni-app项目的“nativeplugins”下,还需要在manifest.json文件的“App原生插件配置”项下点击“选择本地插件”,在列表中选择需要打包生效的插件:


image.png

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

推荐阅读更多精彩内容