1、引言

跨端开发如何兼顾效率与性能?UTS给出完美答案——用TypeScript语法直接调用原生能力,编译生成高质量Kotlin/Swift代码。本次技术讲解将带您掌握UTS插件开发精髓,解锁跨平台开发新方式。

2、基础概念与环境准备

2.1 为什么需要UTS

  1. 传统跨平台开发的痛点:

  • 性能瓶颈:JavaScript 桥接带来的性能损耗。

  • 功能限制:无法充分利用各平台最新特性。

  • 开发效率:需要维护多套代码,学习成本高。

  • 体验差异:难以实现真正的原生体验。

  1. UTS 的优势:

  • 原生性能:直接编译为平台原生代码,无运行时性能损耗。

  • 类型安全:完整的 TypeScript 类型系统支持。

  • 开发效率:一套代码,多端运行,降低维护成本。

  • 生态丰富:可直接调用各平台原生 API 和第三方库。

2.2 UTS 插件是什么

  1. UTS 插件是一种特殊的 UniApp 插件,它使用 UTS 语言编写,能够:

  • 封装 Android、iOS 等平台的原生功能。

  • 提供统一的 JavaScript API 接口。

  • 在编译时转换为各平台原生代码。

  • 实现真正的"一次编写,处处运行"。

  1. UTS 插件的核心价值:

  • 将原生能力以标准化的方式暴露给 JavaScript 层。

  • 保持原生性能的同时提供跨平台一致性。

  • 扩展 UniApp 生态系统的能力边界。

2.3 开发环境搭建

  • HBuilderX:必须是支持 UTS 的版本(通常是 Alpha 版)。这是唯一的开发工具。

  • 操作:打开 HBuilderX -> 文件 -> 新建 -> 项目 -> uni-app 项目 -> 选择 uts插件uni-app x 项目模板。

  • Android 环境

  • 安装 Android Studio,主要用于安装 SDK 和构建工具。

  • 在 HBuilderX 中设置 Android 模拟器或连接真机。

  • iOS 环境

  • 必须有一台 macOS 设备。

  • 安装 Xcode 和命令行工具。

  • 申请 Apple Developer 账号(真机调试和发布必需)。

3、UTS 语法与原生交互核心

3.1 UTS 语言

  • 基本类型:大部分和 TS 一致。

let name: string = "UTS"; // 字符串
let count: number = 100;  // 数字
let isFinished: boolean = false; // 布尔值
  • 数组和字典:
let arr: Array<string> = ["a", "b", "c"]; // 数组
let map: Map<string, any> = new Map(); // 字典
map.set("key1", "value");
map.set("key2", 123);
  • 平台特有类型:

  1. UTS 允许你直接使用原生平台的类型。

  2. 但为了代码的跨平台性,通常需要条件编译。

// Android 平台类型
// #ifdef APP-ANDROID
let context: android.content.Context
let intent: android.content.Intent
// #endif

// iOS 平台类型
// #ifdef APP-IOS
let view: UIView
let controller: UIViewController
// #endif

3.2 与 Android (Kotlin) /iOS交互

  • 导入原生类
// 引用android api
import Context from "android.content.Context";
// 导入 Android 的 Toast 类
import Toast from "android.widget.Toast";
// 获取android系统 application上下文
const context = UTSAndroid.getAppContext();

// 导入 iOS 的 UIKit 框架 (通常已自动导入,无需手动)
// 直接使用 UIKit 中的类,如 UIApplication, UIViewControllerv
  •  调用静态方法和实例方法
export function showToastAndroid(message: string) {
    // 获取 UniApp 的上下文,这是一个 Android Context
    const context = UTSAndroid.getAppContext();
    // 调用 Toast 的静态方法 makeText
    const toast = Toast.makeText(context, message, Toast.LENGTH_SHORT);
    // 调用实例方法 show
    toast.show();
}
  • 调用 API
export function showToastIOS(message: string) {
    // 获取当前活动的 UIViewController
    const controller = UTSiOS.getCurrentViewController();
    // 创建 UIAlertController
    const alert = new UIAlertController(message, null, UIAlertControllerStyle.alert);
    // 显示 Alert
    controller.presentViewController(animated = true, completion = null);
}

4、UTS 插件开发实战

4.1 项目结构与规范

一个标准的 UTS 插件目录如下:

my-uts-plugin/

├── package.json        // 插件的配置文件,定义标识、依赖等

└── utssdk/
    ├── interface.uts   // 统一接口定义
    ├── unierror.uts   // 错误处理类
    ├── app-android/
    │   ├── libs/       // Android 依赖库
    │   ├── AndroidManifest.xml  // Android 配置
    │   ├── config.json // Android 插件配置
    │   └── index.uts   // Android 平台的具体实现
    └── app-ios/        
        ├── config.json // iOS 插件配置  
        └── index.uts   // iOS 平台的具体实现

package.json 为 uni_modules 插件配置清单文件,负责描述插件的基本配置。

package.json 示例:

{
	"id": "ly-aio",
	"displayName": "ly-aio",
	"version": "1.0.0",
	"description": "ly-aio",
	"keywords": [
        "ly-aio"
    ],
	"repository": "",
	"engines": {
		"HBuilderX": "^3.6.8",
		"uni-app": "^3.1.0",
		"uni-app-x": "^3.1.0"
	},
	"dcloudext": {
		"type": "uts",
		"sale": {
			"regular": {
				"price": "0.00"
			},
			"sourcecode": {
				"price": "0.00"
			}
		},
		"contact": {
			"qq": ""
		},
		"declaration": {
			"ads": "",
			"data": "",
			"permissions": ""
		},
		"npmurl": "",
		"darkmode": "-",
		"i18n": "-",
		"widescreen": "-"
	},
	"uni_modules": {
		"dependencies": [],
		"encrypt": [],
		"platforms": {
			"cloud": {
				"tcb": "-",
				"aliyun": "-",
				"alipay": "-"
			},
			"client": {
				"uni-app": {
					"vue": {
						"vue2": "-",
						"vue3": "-"
					},
					"web": {
						"safari": "-",
						"chrome": "-"
					},
					"app": {
						"vue": "-",
						"nvue": "-",
						"android": "-",
						"ios": "-",
						"harmony": "-"
					},
					"mp": {
						"weixin": "-",
						"alipay": "-",
						"toutiao": "-",
						"baidu": "-",
						"kuaishou": "-",
						"jd": "-",
						"harmony": "-",
						"qq": "-",
						"lark": "-"
					},
					"quickapp": {
						"huawei": "-",
						"union": "-"
					}
				},
				"uni-app-x": {
					"web": {
						"safari": "-",
						"chrome": "-"
					},
					"app": {
						"android": "-",
						"ios": "-",
						"harmony": "-"
					},
					"mp": {
						"weixin": "-"
					}
				}
			}
		}
	}
}

4.2 实战案例:开发一个调用Android第三方sdk来显示/隐藏状态栏的插件

前提:我们在已有的项目中进行插件开发。

步骤:

  1. 在uni_modules目录右键 -> 新建uni_modules插件 -> 输入插件名 -> 选择UTS插件-API插件 -> 创建。

生成ly-aio插件目录:

2. 在app-android/libs/目录下导入第三方aar文件。

3. 在app-android/index.uts文件中调用第三方sdk提供的方法。

import DeviceManager from 'com.example.cabinet.Control';

const context = UTSAndroid.getAppContext();

const manager = DeviceManager.getInstance(context);

/**
 * 显示/隐藏导航栏
 */
export const lyShowOrHideNaviBar = (isShow: boolean): void => {
	manager.lyShowOrHideNaviBar(isShow);
}

/**
 * 显示/隐藏状态栏
 */
export const lyShowOrHideStatusBar = (isShow: boolean): void => {
	manager.lyShowOrHideStatusBar(isShow);
}

4. 在vue组件中使用该插件的代码。

//在页面中先import
import { lyShowOrHideNaviBar } from "@/uni_modules/ly-aio"

...

//在页面方法中调用
function changeBar(type: boolean) {


	try {
		lyShowOrHideNaviBar(type)
	} catch (err) {
		// console.log(err)
	}
	
	uni.showToast({
		title: "操作成功",
		icon: "success"
	})
}

4.3 高级特性:异步操作与 Promise

如果原生操作是异步的(如网络请求),最好的方式是返回一个 Promise。

注意:目前 UTS 仅Android支持promise执行异步任务,iOS还不支持。类似场景可以使用setTimeOut。

// 在 app-android -> index.uts 中定义返回 Promise 的函数
export function fetchData(url: string): Promise<string> {
    // #ifdef APP-ANDROID
    return fetchDataAndroid(url);
    // #endif
}

// 在 app-android -> index.uts 中实现 (以 OkHttp 为例)
import OkHttpClient from "okhttp3.OkHttpClient";
import Request from "okhttp3.Request";

export function fetchDataAndroid(url: string): Promise<string> {
    return new Promise((resolve, reject) => {

        const client = new OkHttpClient();
        const request = new Request.Builder().url(url).build();

        // 异步调用
        client.newCall(request).enqueue(UTSAndroid.createAsyncCallback(
            (response: any) => {
                // 成功回调
                if (response.isSuccessful()) {
                    resolve(response.body().string());
                } else {
                    reject(new Error(`HTTP ${response.code()}`));
                }
            },
            (e: Error) => {
                // 失败回调
                reject(e);
            }
        ));
    });
}

在 JS 就可以用 async/await.then().catch() 来调用:

import { fetchData} from "@/uni_modules/ly-aio"

...

fetchData("https://api.fetch.com/data")
    .then(data => { console.log(data); })
    .catch(err => { console.error(err); });

5、总结

UTS插件开发让开发者使用TypeScript语法编写跨平台原生插件,直接编译为Android/iOS原生代码,实现“一次开发,多端运行”。它完美融合了Web开发效率和原生应用性能,支持条件编译处理平台差异,提供完整的类型安全和Promise异步支持。这套方案大幅降低了原生开发门槛,是UniApp生态中扩展原生能力的核心技术。

6、附录

6.1 常用资源链接

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐