xChar
·3 months ago

客户端原生大佬狂喜: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 插件]]》

Loading comments...