我写这篇文章为的是理清思路,将这段时间的所见所得和跨过的坑梳理一遍。这里不能代表官方文档的覆盖量,强烈建议看一遍官方文档后再来看此篇文章,至少能把一些不明白的地方弄明白。希望这套步骤能增加新手接入的成功率,希望你从中学会,获益。以上是我的初衷。
刚好有一个需求对接,在uni中加入原生的功能,uni开发跟我要SDK文件,由于之前我也写过一个SDK,于是就把SDK丢给uni开发让他去配置,结果怎么也跑不通,我心想uni不是号称可以替代原生开发吗?怎么连framework都用不了,后来才知道是我大意了。在仔细阅读文档之后,开始了我的 - 比生孩子还难的爬坑之路。
准备阶段
- Xcode
- HBuilderX
- uni-SDK包
一、开发插件
插件开发包含了制作.framework或.a工程、导入制作、封装uni函数这三个方面。
1、制作原生framework或Library
在uni开发中,iOS原生插件代表framework或.a文件。所以首先创建一个这样子的工程,可以参考framework项目指引(Swift)。
我们不急着将工程生成为framework文件,因为这样直接生成偏原生向的.framework文件在uni中是不可用的,参考上述指引(1~6步),并将它导入HBuilder-uniPluginDemo工程中
2、导入插件
1.将刚刚创建的工程文件拖到HBuilder-uniPluginDemo子目录下,并打开同级目录下HBuilder-uniPlugin.xcodeproj工程
2.选中主工程,右键选择Add Files to "Project...",选中插件目录中的xcodeproj文件,分为以下两步
3.导入framework
选择主工程 - Targets - Build Phases
4.导入头文件路径
选择插件工程 - targets - Build Settings
我们需要的DCUni头文件及Weex头文件都存在ins下,所以必须指定这个路径导入
5.根据需要新建继承自DCUniModule、DCUniComponent的OC文件
以上已经做完了所有导入步骤,但如果想要完全运行,还需要:
检查插件关联项
配置规范的接口代码
3、代码规范
原生插件是基于 DCUniPlugin 规范来实现扩展原生的功能,其特点包括:
- module:不需要参与页面布局,只需要让uni具备调用原生能力。
- component:需要直接参与uni页面布局。
- 在插件中可以同时有多个文件,来增加它的不同的能力和功能划分。
(1)uni-app
# 获取 module
const swiftSdk = uni.requireNativePlugin("SwiftObject-SwiftModule");
# 调用异步方法
let bl = swiftSdk.swiftLogFunc({
log: "ok"
},(function(e) {
//上号结果回调
console.log(e)
}))
# 调用同步方法
var ret = swiftSdk.swiftLogWithBoolFunc({
'ok': 'uni-app'
})
复制代码
(2)原生module
以module为例,分为同步和异步方法:
异步方法(不带返回值,有回调)
// 通过宏 UNI_EXPORT_METHOD 将异步方法暴露给 js 端
UNI_EXPORT_METHOD(@selector(swiftLogFunc:callback:))
-(void)swiftLogFunc:(NSDictionary *)options callback:(UniModuleKeepAliveCallback)callback {
NSString *log = options[@"log"];
callback(@{@"success": log},NO);
}
复制代码
同步方法(带返回值)
UNI_EXPORT_METHOD(@selector(swiftLogWithBoolFunc:))
-(BOOL)swiftLogWithBoolFunc:(NSDictionary *)options {
NSString *log = options[@"log"];
return YES;
}
复制代码
Module默认在主线程,用uniExecuteThread(DCUniModule)可控制线程
入参只能传键值对,在开发时与uni端定义好,需要注意key字符串检查和value类型检查
UniModuleKeepAliveCallback 第一参数回调参数 第二参数bool 为no方法完成后会自动释放
二、运行方式
理解
运行方式分为两种,即HBuilderX运行和Xcode运行。
在HbuilderX,所依赖的是基座,通过安装基座,选择在真机或者模拟器上运行
在Xcode,通过HBuilderX生成本地打包资源文件,运行在Xcode编译的真机模拟器上
究竟这两种方式有什么不同呢?下面主要细说这两个部分的区别。
首先是打包方式。
选择HBuilderX运行,就需要我们生成一个.framework或.a的插件包(也就是做一个uni可配的原生SDK包),并将包放置在uni项目的指定文件,通过制作自定义基座,选择自定义基座运行
选择Xcode运行,我们不需要制作插件包,而是需要用HBuilderX生成一个本地包,放在原生项目的指定文件,配置uni信息,然后运行即可
其次是关联项配置方式。
选择HBuilderX运行,就需要配置package.json,以确保原生资源能在打包编译时被找到
选择Xcode运行,我们可以不用配置package.json,但是要配置HBuilder-uniPlugin-Info.info,以确保在Xcode上编译的uni基座可以找到原生插件
检查配置插件关联项
要想将自定义基座中包含的插件运行起来,需要配置正确完善的信息内容。比较好记的是:
package.json关联项对应的是HBuilderX调试
HBuilder-uniPlugin-Info.info关联项对应的是xcode调试
操作步骤
1.运行调试
HBuilderX
1.1 配置package.json关联项参考
{
"name": "Swift Log",
"id": "SwiftObject",
"version": "1.0.0",
"description": "uni示例插件",
"_dp_type": "nativeplugin",
"_dp_nativeplugin": {
"ios": {
"plugins": [{
"type": "module",
"name": "SwiftObject-SwiftModule",
"class": "SwiftModule"
}],
"embedSwift": true,//是否开启swift支持
"integrateType": "framework",
"deploymentTarget": "9.0"
}
}
}
复制代码
1.2 整合插件包目录格式
在nativeplugins文件下创建一个和插件名称一样的文件夹,该文件夹下最多只能包含三个内容:ios、android、package.json
(1)ios文件夹:用于存放.framework或.a插件,也可以用来存放BundleResources文件夹(管理bundle资源)
(2)android文件夹:用于存放.aar插件
(3)package.json:用于配置关联项
1.3 选择原生插件
1.4 开始制作自定义基座
BundleID:AppID,对应profile文件
profile文件:.mobileprovision描述文件
证书文件:通过钥匙串导出生成的.p12文件
证书秘钥:设置p12文件时的秘钥
1.5 制作自定义基座(成功)
1.6 选择基座运行
1.7 运行到真机或模拟器
1.8 真机安装(成功)
Xcode
1.1 配置Xcode HBuilder-uniPlugin-Info.info关联项参考
<dict>
<key>plugins</key>
<array>
<dict>
<key>class</key>
<string>SwiftModule</string>
<key>name</key>
<string>SwiftObject-SwiftModule</string>
<key>type</key>
<string>module</string>
</dict>
</array>
</dict>
复制代码
1.2 打开工程HBuilder-uniPlugin.xcodeproj
1.3 替换HBuilder-uniPlugin-Info.info里面的dcloud_appkey字段,申请appkey
1.4 替换本地uni资源
(1)使用HBuilderX生成本地包
(2)导出本地包
(3)替换资源,确保三者一致
1.5 切换Targets 为 HBuilder Schemes
1.6 运行
调试的差异
你可以从两种方式任意选择一种调试uni-iOS项目,需要注意的是。
使用HBuilderX 加入自定义基座运行,每次修改插件都需要重新打包基座
使用Xcode,可以任意修改插件内容,当修改uni内容只需要生成本地包文件就行了(唯一的就是当我们切换插件中的函数,需要将原有的app删掉才能生效)
2.打包ipa文件
Xcode打包:Xcode - Product - Archive(适用于发布打包)
HBuilderX自定义基座打包,会在unpackage/debug中生成ipa文件(仅用于调试)
三、可能会遇到的问题
云端拉取插件无法导入HBuilderX
如果遇到云端插件无法导入,需要解压后手动导入
1.找到HBuilderX.app,右键"显示包内容"
2.将解压后的文件导入HBuilderX-plugins目录下
3.在此路径下执行
../npm/npm install --save
复制代码
4.重启HBuilderX
需要使用iOS相关第三方库
在制作原生插件的过程中,我们可能会用到许许多多的第三方库,并且uni官方文档也告诉我们可以用,怎么样使用文档却并没有明确交代,遇到这种情况,可以使用手动制作
(1)需要在github下载需要用到的第三方库,并制定对应版本
(2)打开第三方库项目,选择Build Phases并导入run script(# framework项目指引(Swift)第5步)
(3)选择Build Settings,搜索ios 调整target版本
(4)分别在模拟器和真机环境Build Code
(5)将做好的.framework文件,放入uni-Demo SDK/Libs路径下
(6)选择需要用到第三方库的插件工程,Build Settings - Framework Search Paths,拖入文件路径
(7)导入主项目
(8)import导入和编译
自定义基座打包失败
**<Weex>[warn]WXBridgeContext.m:1310, jsLog: [JS Framework] 当前运行的基座不包含原生插件[SwiftObject-SwiftModule],请在manifest中配置该插件,重新制作包括该原生插件的自定义运行基座 __WARN**
- 排查关联项是否正确配对
- 如果关联项正确,查看log日志中输出的内容,如果含有# Symbol(s) not found for arm64且包括第三方库的相关错误,则可能是云端或者手动创建的第三方库配置有问题
码字不易,多多支持。希望大家越来越好。