辛宝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 插件]]》

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。