辛宝Otto

辛宝Otto 的玄酒清谈

北漂前端程序员儿 / 探索新事物 / Web Worker 主播之一/内向话痨
xiaoyuzhou
email

客户端原生大佬狂喜:uni-app x 支持原生混编了!

客户端原生大佬狂喜:uni-app x 支持原生混编了!

本文背景#

最近 uni-app x 发布了全新版本,其中有一点是 uni-app x 4.25 支持原生混编了,也就是可以直接使用 kotlin/java/swift 代码了,客户端原生大佬们可以火力全开了!

新增 编译器 uts 插件支持 Kotlin、Java、Swift 代码混编

很多人和我一样,需要使用 uni-app x 开发 app,但对客户端原生开发 (后面统一叫 “原生开发”) 比较陌生,又不熟悉相关领域知识。可以借助 UTS 语言来进行原生功能开发。

也有很多原生开发老手参与开发 uni-app x,熟悉原生开发的各种底层细节,更倾向于使用已有的原生开发经验。

两个不同的人群需求不同,会有一些不同角度的产品建议反馈:

  • 前端反馈实现页面布局、业务开发快,但是原生开发不熟,有问题解决不了
  • 原生开发反馈,希望复用已有的原生 SDK、原生工具包

大家的目标是一样的,加速 app 开发落地,早完工不加班!

本文简单介绍原生混编的基础概念、相关用法、进阶提升等。

为什么会有原生混编?#

这个功能目标群体是谁,有什么用,对我有影响吗?

uni-app x 开发应用,以往要实现业务逻辑,调用原生功能时候之前需要使用 UTS 语言来编写兼容代码,通过编译器来转换成 Kotlin 和 Swift。

这对前端同学比较友好:因为 UTS 的语法是和 TS 很像,只要知道原生怎么写,转换一下就可以上手了。实现了让前端工程师有能力调用客户端原生功能。

另一方面,对原生开发老手来说就有需要吐槽的地方了,还要额外学习 UTS 和 UTS 插件等东西,希望可以复用以后的原生开发知识。

这次更新就支持了在 UTS 插件中使用原生混编功能。这里举一个例子来进行说明。

关联文章:

  • [[如何快速学习和测试 Swift 和 UIKit 代码?]]
  • [[如何快速学习和测试 Android Kotlin 代码?]]

这里以 iOS 为主要介绍平台,安卓大同小异,为了一致的阅读体验,在文章的末尾放出安卓相关代码。

新概念主要先看思路。

iOS 里查询当前电量#

熟悉 uni-app x 的用户可能听过好几次查询当前手机电量的案例了,没办法这个是在太经典了。

假设现在我要求在 app 查询当前手机电量,如果当前电量比较高,比如 80% 以上时候 app 应用就使用高级动画,低于这个值就开启普通动画。

如果使用 uni-app x 获取当前手机电量,这个需求是一个原生需求,需要调用客户端的 api 来获取。这个需求 uni-app x 已经封装好了这个 api,直接使用 uni.getBatteryInfo 就得到了。

这里我们假装没有,需要自己实现。

iOS 原生代码举例#

可以通过问原生同事、问 AI、翻阅 uni-app x 的开源代码,得知 iOS 查询电量的逻辑是这样。

import UIKit

func getBatteryLevel() -> Float {
    // 开启电池监测
    UIDevice.current.isBatteryMonitoringEnabled = true
    
    // 获取当前电量
    let batteryLevel = UIDevice.current.batteryLevel
    // 转换为百分比
    return batteryLevel * 100
}

// 获取电量并打印·
let currentBatteryLevel = getBatteryLevel()
print("当前电量: \(currentBatteryLevel)%")

在混编开发之前#

在 uni-app x 支持混编功能之前,我们需要使用 UTS 翻译以上代码,通过 UTS 编译器转为原生:知道原生如何写 - 翻译为 UTS - 翻译为 Swift。

UTS 代码大致如下,删除了函数导出、格式化等逻辑。

import { UIDevice } from "UIKit";
UIDevice.current.isBatteryMonitoringEnabled = true
const batteryLevel = Number(UIDevice.current.batteryLevel * 100)

通过讲逻辑拆分为 UTS 插件,在编译时候通过 UTS 编译器转换为 Swift 代码。

这里安卓平台导入包的过程不完全一样,一般推荐的做法还是按照平台拆分实现功能。

在混编开发之后#

有了原生混编,很多事情就简单多了。这里如果你对 UTS 开发插件还不熟悉,可以参考 [[新手向:包装 UTS 插件]],主要介绍了 UTS 插件如何开发。本文主要展示混编的大致思路,细节不一一展开了。

经典的 UTS 插件目录结构是

uni_modules
- webworker-batteryStatus
-- utssdk
--- app-ios
---- index.uts
-- package.json

在 UTS 插件的 app-ios/index.uts 中新建 NativeCode.swift,人如其名,这个文件是原生 swift 文件。

NativeCode.swfit 文件内容如下,这是官方推荐的一种写法。

import UIKit

public class NativeCode {
  static func getBatteryLevelSwift() -> Float {
      // 开启电池监测
      UIDevice.current.isBatteryMonitoringEnabled = true
      
      // 获取当前电量
      let batteryLevel = UIDevice.current.batteryLevel
      // 转换为百分比
      return batteryLevel * 100
  }
}

在 UTS 中如何调用?

index.uts 代码如下

export function getBatteryLevelSwift() : Float {
  return NativeCode.getBatteryLevelSwift()
}

使用就很简单了,引用包,调用方法即可。

<template>
  <view>
    <view>{{currentLevel}}</view>
    <button @click="getLevel"> 电量</button>
  </view>
</template>

<script setup>
  import { getBatteryLevelSwift  } from '../../uni_modules/webworker-batteryLevel'
  const currentLevel = ref(0)
  const getLevel = () => {
    console.log('click button')
    // console.log(getBatteryLevelSwift())
    const res = getBatteryLevelSwift()
    currentLevel.value = res
  }
</script>

image.png

通过

  • 原生开发逻辑
  • uts 包装逻辑
  • uvue 中调用

可以轻松实现混编开发。

安卓实现混编#

和 iOS 类似,也是在 uni_moduels 的 app-android 目录添加 index.utsNativeCode.kt

其中 NativeCode.kt 内容大致

package uts.sdk.modules.ottoBatteryLevel;
import android.content.Context
import android.os.BatteryManager

object NativeCode {
  fun getBatteryLevel(context: Context): Int {
      val batteryManager = context.getSystemService(Context.BATTERY_SERVICE) as BatteryManager
      val batteryLevel = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
      return batteryLevel
  }
}

其中 index.uts 内容如下

import Context from "android.content.Context";

export function getBatteryLevel() : Int {
  const context = UTSAndroid.getAppContext()!;
  return NativeCode.getBatteryLevel(context)
}

其他部分和 ios 一致,在 uvue 调用 uts 插件。

接下来做什么?#

希望通过这篇文章介绍,可以让你对 UTS 插件开发、原生混编、uni-app x 开发有进一步的理解。

有了大杀器可以探索更多内容了。接下来可以做什么?

官方的 demo 实现学习更多细节#

官方开源了 hello uts 仓库,可以从这个案例了解更多细节。

uni_modules/uts-tests/utssdk/NativeCode.uts · dev · DCloud / Hello UTS · GitCode

官方文档了解更多技术细节#

详细说明了原生混编的来龙去脉,更加详细。
https://doc.dcloud.net.cn/uni-app-x/plugin/uts-plugin-hybrid.htm

学习 uts 插件开发#

参考 《[[新手向:包装 UTS 插件]]》

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。