iOS uni-app原生插件(native plugin)踩坑

打印 上一主题 下一主题

主题 1651|帖子 1651|积分 4953

什么是 uni-app ?

   uni-app 是一个利用 Vue.js 开辟所有前端应用的框架,开辟者编写一套代码,可发布到iOS、Android、Web(响应式)、以及各种小程序(微信/支付宝/百度/头条/飞书/QQ/快手/钉钉/淘宝)、快应用等多个平台。
  什么是 uni-app 原生插件, 为什么要利用原生插件

   uni原生插件指的是将您原生开辟的功能按照规范封装成插件包,然后即可在 uni-app 前端项目中通过js调用您开辟的原生本领。
  
  uni原生插件: uni-app项目中利用,uni-app的js运行在独立的jscore里,而不是webview里,它的原生扩展是基于开源项目weex架构的扩展机制。
  
  当HBuilderX中提供的本领无法满足App功能需求,需要通过利用Andorid/iOS原生开辟实现时,可利用App离线SDK开辟原生插件来扩展原生本领。
  参考: 原生插件开辟
原生插件类型:

   

  • Module模式:本领扩展,无嵌入窗体的UI控件。大部门插件都是属于此类,比如调用计步器API。代码写法为通过js进行require,然后调用该插件对象的方法。如涉及一些弹出框、全屏ui,也仍然属于Module模式。类似于前端里的js sdk。
  • Component模式:在窗体中内嵌表现某个原生ui组件。比如窗体局部内嵌某个舆图厂商的map组件,上下混排其他前端内容,就需要把这个原生舆图sdk封装为Component模式。代码写法与vue组件雷同,在template里写组件标签。类似于前端里的vue组件。
  uni-app在App端支持双渲染引擎,支持vue和nvue两种页面,vue页面基于webview排版引擎渲染,nvue页面基于优化版的weex原生排版引擎渲染,weex的插件也可以拿到uni-app生态中利用。
  

  • vue页面中仅支持利用Module类型的原生插件,不支持调用同步方法返回数据
  • nvue页面中支持利用Module和Component两种类型的原生插件。也就是如需实现嵌入页面的ui组件,前提是该页面需要利用nvue编写。
  总结一下 Module 不含 UI, 而 Component 是 UI 组件。 Component 必须在 nvue 页面里调用,Module 可以在 vue 和  nvue 页面调用。
uni原生插件上线步调

   

  • 下载App离线SDK

    • Android平台App离线SDK下载
    • iOS平台App离线SDK下载

  • 配置原生开辟情况,在原生情况中开辟调试插件业务逻辑

    • Android平台需利用AndroidStudio
    • iOS平台需XCode11+(需Mac情况)

  • 开辟调试完成后导出原生库文件

    • Android平台可以是jar或aar包
    • iOS平台可以是.a或.framework包

  • 生成uni原生插件包(zip)

    • 配置package.json文件
    • 与前面导出的原生库文件一起打包

  • 在HX中利用uni原生插件包提交云端打包,验证uni原生插件包是否正确
  • 上传uni原生插件包到插件市场审核
  • 审核乐成后其他开辟者可购买、利用uni原生插件
  注意:
App原生语言插件已不再维护。请改用同时支持 uni-app 和 uni-app x 的 uts插件
   2024年8月1日起,插件市场将不再吸收新的App原生语言插件。
  基于此教程开辟的原生插件,只可以本地利用,不能发布到插件市场了!
开辟教程

参考: iOS 插件开辟教程, 里面有具体的开辟步调。
也可以看这个: iOS uni-app 原生插件开辟-CSDN博客
踩坑的点: 

1. 自界说事件, 事件名对不上

   对于每个组件默认提供了一些事件本领,如点击等。假如想给我们的舆图组件提供 mapLoaded 事件。

  uni-app 中是通过 @事件名="方法名" 添加事件,如下方代码所示在nvue中,给舆图组件添加mapLoaded 事件
  1. <template>
  2.     <div>
  3.         <dc-testmap style="width:750rpx;height:300px" @mapLoaded="onMapLoaded"></dc-testmap>
  4.     </div>
  5. </template>
  6. <script>
  7. export default {
  8.     methods: {
  9.         onMapLoaded:function(e) {
  10.             // 原生端传递的数据保存在 e.detail 中
  11.             console.log("map loaded: "+JSON.stringify(e.detail))
  12.         }
  13.     }
  14. }
  15. </script>
复制代码
对应的原生端实现

我们需要添加一个 BOOL 类型成员变量 mapLoadedEvent 用来记载该事件是否见效,如下方代码所示:
  1. /// 前端注册的事件会调用此方法
  2. /// @param eventName 事件名称
  3. - (void)addEvent:(NSString *)eventName {
  4.     if ([eventName isEqualToString:@"mapLoaded"]) {
  5.         _mapLoadedEvent = YES;
  6.     }
  7. }
  8. /// 对应的移除事件回调方法
  9. /// @param eventName 事件名称
  10. - (void)removeEvent:(NSString *)eventName {
  11.     if ([eventName isEqualToString:@"mapLoaded"]) {
  12.         _mapLoadedEvent = NO;
  13.     }
  14. }
复制代码
原生端向前端发送事件

在舆图加载完毕的方法中触发 mapLoaded 事件
  1. - (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView {
  2.     if (_mapLoadedEvent) {
  3.         // 向前端发送事件,params 为传给前端的数据 注:数据最外层为 NSDictionary 格式,需要以 "detail" 作为 key 值
  4.         [self fireEvent:@"mapLoaded" params:@{@"detail":@{@"mapLoaded":@"success"}} domChanges:nil];
  5.     }
  6. }
复制代码
约定了事件名是 mapLoaded, 实际发过来却是 map-loaded,找了半天原因,是由于 vue 的版本不对, 上面用的是 vue2, 而我用的是 vue3。 vue3 会把事件改写成 - 毗连的样式。
参考: uniapp项目第二阶段开辟遇到的问题汇总_uniapp fireevent-CSDN博客

2.  打包的时候支持的 iOS 版本对不上

云端打包的自界说基座,iOS 版本过低从 iOS13.0 开始支持,我开辟的插件是基于 iOS15开始的。打包链接出问题了。之后将插件的版本降低到 iOS13 后问题得以办理。






免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

九天猎人

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表