# UTS plugin introduction

# 介绍

HBuilderX 3.6+ supports uts plugin

Official QQ exchange group for UTS plug-in development: 527828934 Click here to join

# 什么是uts语言

uts, full name uni type script, unified, strong type, scripting language.

It can be compiled into programming languages for different platforms, such as:

  • web platform, compiled to JavaScript
  • Android platform, compiled to Kotlin
  • iOS platform, compiled to Swift (supported by HX 3.6.7+ version)

uts adopts the same syntax specification as ts and supports most ES6 APIs.

如需详细了解uts语法,另见uts语法介绍

uts语言,

  • 可以用来开发独立App,即uni-app x
  • 也可以用来开发插件,即uts插件。

# What is uts plugin

uts插件,指利用uts语法,操作原生的API(包括手机os的api或三方sdk),并封装成一个uni_modules插件,供前端调用。

  • uni-app中,是js来调用uts插件。(HBuilderX 3.6支持vue3编译器,3.6.8支持vue2编译器)
  • uni-app x中,是uts来调用uts插件。(HBuilderX 3.9支持)

也就是一个uts插件,可以同时支持uni-app和uni-app x。

为了兼容全端,uts插件可以分目录写所有平台代码,也就是一个uts插件除了支持App的扩展,还可以支持web、小程序。

比如这个uts插件,电量,其源码在https://gitcode.net/dcloud/uni-api/-/tree/master/uni_modules/uni-getbatteryinfo,内部有多个目录(app-android、app-ios、web、mp-weixin、mp-alipay...),在非App目录也可以写js。

这个电量插件在uni-app和uni-app x中均可以使用。

uts插件分api和组件。这和uni-app的组件、api的概念是一样的。

  • api插件:uts插件扩展了api能力,在script里调用
  • 组件插件:uts插件扩展了界面组件,在template里调用。它是要内嵌在页面中。

api插件也可以操作界面,但更多是独立的全屏窗口或弹出窗口。而不能嵌入在template中。

比如lottie动画的uts插件,就是一个组件插件。https://ext.dcloud.net.cn/plugin?id=10674,其源码在https://gitcode.net/dcloud/uni-component/-/tree/master/uni_modules/uni-animation-view

![uts plugin structure](https://native-res.dcloud.net.cn/images/uts/UTS%E7%BB%93%E6%9E%84%E7%A4%BA%E6%84%8F %E5%9B%BE1.png)

# The difference between uts plugin and uni native language plugin

uts 插件编译到 app 平台时,在功能上相当于 uni-app 之前的 app 原生插件。都是给app扩展原生能力。

开发 uts 插件不需要熟悉 Kotlin 和 Swift 的语法,因为使用的是 uts语法。但需要熟悉 Android 和 iOS 的系统 API,至少需要知道什么原生能力在哪个API里。

Before HBuilderX 3.6, uni-app had only one native plug-in on the App side, that is, a plug-in developed with java or Objective-C.

After the launch of uts, the original "App native plug-in" was renamed "App native language plug-in".

Different names mean that they require developers to write in different languages. But the same results are obtained, and they are finally compiled into native binary code.

native language plugin uts plugin
Development language java/oc uts
Development Environment Android Studio/XCode HBuilderX
Packaging method Outputs such as plug-in aar Generate native code when compiling
js层调用方式 uni.requireNativePlugin() 普通的js函数/对象,可以直接 import,支持摇树优化
支持项目类型 uni-app uni-app和uni-app x

相对原生语言插件,uts插件的优势:

  1. Unified programming language (uts), one language to develop all platforms, really big front-end.
  2. The development tool (HBuilderX) is unified, eliminating the need to build a complex native development environment.
  3. Fewer concepts to understand in plug-in packaging. Traditional native language plug-ins need to handle communication between js and the native layer, use various special conversions, and use special syntax imports. There are many things to pay attention to. **uts is unified into a pure front-end concept, which is simple and clear. **
  4. uts 下前端和原生可以统一在 HBuilderX 中联调。而传统原生语言插件需要在多个开发工具间切换,联调复杂。
  5. 插件市场的uts插件支持下载后自己固定版本。而付费的原生语言插件只能使用最新版。
  6. 插件市场的uts付费插件支持源码版销售和源码版权保护机制。而付费的原生语言插件不支持源码版销售。
  7. uts插件可同时支持uni-app和uni-app x。

如果您是插件作者,可以了解更多uts插件和uni原生语言插件对插件作者的区别。详见

# Difference between uts plugin and Native.js

  • Native.js 运行在js上,通过反射调用os api。功能和性能都不及原生
  • uts does not run in the js engine on the app, it is truly native.

# 创建uts插件

# uts plugin directory structure

Under the uni-app project, a separate directory utssdk is provided to store uts plugins.

Of course, the official recommendation is to use uni_modules, which is a better package management solution.

First make sure that the uni_modules folder exists in the root directory of the project. If it does not exist, you need to create one manually.

Plugin Directory

# New step disassembly

Right click on the uni_modules directory -> New Plugin

New Plugin 1

Select type uts plugin

New Plugin 2

**In order to avoid conflicts with other plugins in the plugin market, it is recommended to create your own plugin prefix name. **

uts plugin directory structure

New Plugin 3

# package.json

package.json is the uni_modules plugin configuration manifest file, which is responsible for describing the basic configuration of the plugin.

{
  "id": "uts-helloworld",
  "displayName": "uts插件示例",
  "version": "0.1",
  "description": "uts插件示例",
  "uni_modules": {
    
  }
}

The above is a default manifest file example, more description about package.json see

# Plugin directory structure

	
┌─common                          // 可跨端公用的uts代码。推荐,不强制
├─static                          // 静态资源
├─utssdk
│	├─app-android                 //Android平台目录
│	│	├─assets                  //Android原生assets资源目录,可选
│	│	├─libs                    //Android原生库目录,可选
│	│	├─res                     //Android原生res资源目录,可选
│	│	├─AndroidManifest.xml     //Android原生应用清单文件,可选
│	│	├─config.json             //Android原生配置文件
│	│	└─index.uts               //Android原生插件能力实现
│	├─app-ios                     //iOS平台目录
│	│	├─Frameworks              //iOS原生依赖的第三方 framework 依赖库存放目录,可选
│	│	├─Libs              	  //iOS原生依赖的第三方 .a 依赖库存放目录,可选
│	│	├─Resources               //iOS原生所依赖的资源文件存放目录,可选
│	│	├─info.plist              //iOS原生所需要添加到主 info.plist 文件中的配置文件,可选
│	│	├─UTS.entitlements        //iOS原生所需要添加到主工程 .entitlements 文件中的配置文件,可选
│	│	├─config.json             //iOS原生配置文件
│	│	└─index.uts               //iOS原生插件能力实现
│	├─web                         //web平台目录
│	│	└─index.uts
│	├─mp-alipay                   // 支付宝小程序平台,可选
│	├─mp-baidu                    // 百度小程序平台,可选
│	├─mp-jd                       // 京东小程序平台(仅限vue2),可选
│	├─mp-kuaishou                 // 快手小程序平台,可选
│	├─mp-lark                     // 飞书小程序平台,可选
│	├─mp-qq                       // QQ小程序平台,可选
│	├─mp-toutiao                  // 抖音小程序平台,可选
│	├─mp-weixin                   // 微信小程序平台,可选
│	├─mp-xhs                      // 小红书小程序平台(仅限vue2),可选
│	├─index.d.ts                  // 插件能力声明,可选,将废弃,推荐使用interface.uts
│	├─interface.uts               // 声明插件对外暴露的API
│	└─index.uts                   // 跨平台插件能力实现,可选
└─package.json                    // 插件清单文件

The index.uts file in the root directory is the main entry point of the program. If there is no index.uts in the root directory of the plug-in, it will look for the index.uts file in the sub-platform directory when compiling to different platforms.

For example, when compiling to the app-android platform, if there is no index.uts in the root directory of the uts plugin, it will search for utssdk/app-android/index.uts. If it is not found, an error will be reported.

When both the index.uts of the sub-platform directory and the root directory index.uts exist, the specific sub-platform directory will be obtained first.

Developers have several ways to organize their code:

  1. Write conditional compilation code in index.uts in the root directory of the plugin. Simple business done with one file
  2. Write conditional compilation in the plug-in root directory index.uts, and import the files of different platforms
  3. Instead of writing index.uts in the root directory, write index.uts directly in the sub-platform directory. When not cross-terminal, such as only making an Android plug-in, it is relatively simple to write

index.d.ts 文件是对当前插件能力的声明,用于语法提示。已不推荐使用,请使用interface.uts。

Because after the uts is written, HBuilderX can automatically recognize the uts api and provide syntax prompts. It is more used to give syntax hints when the subsequent uts plugin encrypts.

If you are not familiar with d.ts, you can search online by yourself, it belongs to ts standard technology.

# App native configuration

# Android platform native configuration

The native configuration of the Android platform exists in the app-android folder, including the following directories or files

directory name/file name purpose
assets Android platform native assets resource directory
libs The third-party jar/aar directory natively referenced by the Android platform
res Android platform native res resource directory
AndroidManifest.xml Android platform native application manifest file
config.json Android平台下的配置文件
index.uts 主入口,interface.uts/index.d.ts声明的能力在Android平台下的实现
# assets

The native assets resource directory of the Android platform. It is recommended to save only the resource files built into the UTS plugin.

In addition to the assets directory under the plugin, there is also under the project. Note the difference between the two. If plug-in user configuration (such as the authorization file of the third-party SDK) is required, the plug-in author should tell the plug-in user in the plug-in documentation that the configuration should be in the Android native application resource directory of the project instead of in the plug-in directory. See details

# libs

The Android platform's native third-party library directory supports the following types of files:

  • jar
  • aar
  • so library

如果封装三方原生sdk为uni-app插件,可以将sdk的jar/aar文件放到此目录,但因为多个uts插件引用相同三方原生sdk时可能会产生冲突,所以如果sdk支持仓储,建议优先使用仓储配置,而不是直接把jar等文件放在libs目录。

仓储配置参考config.json的dependencies

If the third-party sdk used contains the so library, when saving to this directory, it needs to be saved in different directories according to the Android abi type.

For the use of the libs directory, please refer to Hello UTS

# res

The native res resource directory of the Android platform, it is recommended to save only the resource files built into the UTS plug-in.

In addition to the res directory under the plug-in, there is also under the project. Note the difference between the two. The configuration of general users is not placed under the plug-in, but under their own project. Configuration under the project see details

# AndroidManifest.xml

Android native application manifest file, it is recommended to save only the built-in manifest file configuration of the UTS plugin.

In addition to AndroidManifest.xml under the plugin, there is also under the project. Note the difference between the two. The configuration of general users is not placed under the plug-in, but under their own project. Configuration under the project see details

# config.json

The uts plugin is in the native layer configuration file of the Android platform, where you can configure gradle-related content such as dependency repositories.

{
	// Supported CPU types when using NDK, optional (do not copy comments when packaging)
	"abis": [
	    "使用NDK时支持的cpu类型, 可取值armeabi-v7a|arm64-v8a|x86|x86_64"
	],
    // Dependent storage configuration, optional, will be merged into the build.gradle of the native project when packaging (do not copy comments when packaging)
	"dependencies": [
		"androidx.core:core-ktx:1.6.0",
		{
			"id": "com.xxx.richtext:richtext",
			"source": "implementation 'com.xxx.richtext:richtext:3.0.7'"
		}
	],
    // Android系统版本要求,最低Android 5.0(打包时不要复制注释)
	"minSdkVersion": 21,
	"project": {
		"plugins": [
			"com.huawei.agconnect"
		],
		"dependencies": [
			"com.huawei.agconnect:agcp:1.6.0.300"
		]
	}
}
  • abis
    Configure when the plug-in uses the so library developed by NDK, and describe the CPU type supported by the plug-in. Possible values: armeabi-v7a, arm64-v8a, x86, x86_64
  • dependencies
    Configure the storage that the plug-in depends on, which will be merged into the build.gradle of the Android native project when packaging in the cloud Array type, the items in the array can be string type or JSON object For string type items, it will be added to build.gradle as an implementation method dependency. In the above example, "androidx.core:core-ktx:1.6.0" will add the following configuration
dependencies {
  implementation 'androidx.core:core-ktx:1.6.0'
}

For JSON type items, the source field value will be added to build.gradle as the gradle source code, and the "id": "com.xxx.richtext:richtext" item in the above example will add the following configuration

dependencies {
  implementation 'com.xxx.richtext:richtext:3.0.7'
}
  • minSdkVersion
    The minimum version of Android supported by the plug-in, integer type, the value range is Android API Level

The minimum supported version of the default uni-app is 19, namely Android4.4.2

  • project
    • plugins
      此配置将会添加到云端打包工程app及build.gradle文件的“plugins”中:
plugins {
    id 'com.android.application'
    // 前面config.json示例配置将会添加如下配置
    id 'com.huawei.agconnect'
}
+ dependencies  
	此配置将会添加到云端打包工程项目级build.gradle文件的“buildscript > dependencies”中  
buildscript {
    dependencies {
		classpath 'com.android.tools.build:gradle:7.2.0'
		// 前面config.json示例配置将会添加如下配置
        classpath "com.huawei.agconnect:agcp:1.6.0.300"
	}
}

Notice:

  • Android平台原生配置(包括引入、变更三方sdk)均需提交云端打包才能生效,真机运行时需使用自定义基座

  • HBuilderX has built-in android common dependencies: built-in dependency list, developers need to pay attention to two points:

    1 The dependencies involved in the built-in list can be used directly without adding them manually

    2 Do not introduce the same dependencies by manually adding jar/aar, otherwise cloud packaging will fail due to dependency conflicts.

# iOS platform native configuration

There are iOS platform native configurations under the app-ios folder, including the following directories or files

Directory Name/File Name Purpose
Frameworks iOS平台插件需要引用的三方 framework 依赖库存放目录
Libs iOS平台插件需要引用的三方 .a 依赖库存放目录
Resources The resource file storage directory that needs to be referenced by the iOS platform plug-in
Info.plist The iOS platform plug-in needs to be added to the configuration file in the native project Info.plist
UTS.entitlements The iOS platform plug-in needs to be added to the configuration file in the entitlements file of the native project
config.json iOS平台原生工程的配置文件
index.uts 主入口,interface.uts/index.d.ts声明的能力在iOS平台下的实现
# Frameworks

iOS平台插件依赖的三方framework存放目录,支持以下类型文件:

  • framework
  • xcframework

注意:目前支持静态库和动态库

# Libs

HBuilder X 3.7.2+ 版本支持

iOS平台插件依赖的三方.a库存放目录,支持以下类型的.a库:

  • 使用OC语言创建的.a库
  • 使用Swift语言创建的.a库

备注:有关OC及Swift创建的.a库的区别、.a库的使用方法和注意事项详见

# Resources

The native resource directory of the iOS platform, it is recommended to save only the resource files built into the uts plugin. All files in this directory will be added to the application main bundle when cloud packaging.

In addition to the Resources directory under the plug-in, there are also under the project. Note the difference between the two. The configuration of general users is not placed under the plug-in, but under their own project. Configuration under the project [see details](https://uniapp.dcloud.net.cn/tutorial/app-nativeresource-ios.html#%E8%B5%84%E6%BA%90%E6%96%87%E4 %BB%B6-bundle-resources)

# Info.plist

The native Info.plist file configuration of the iOS platform, the configuration information will be merged into the Info.plist of the native project when packaging in the cloud.

In addition to the Info.plist under the plug-in, there is also under the project. Note the difference between the two. The configuration of general users is not placed under the plug-in, but under their own project. Configuration under the project [see details](https://uniapp.dcloud.net.cn/tutorial/app-nativeresource-ios.html#%E9%85%8D%E7%BD%AE%E6%96%87%E4 %BB%B6-info-plist)

Example: Add a custom field TencentLBSAPIKey and enable background positioning

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
	<key>TencentLBSAPIKey</key>
	<string>填写您申请的APIKey</string>
	<key>UIBackgroundModes</key>
	<array>
		<string>location</string>
	</array>
  </dict>
</plist>
# UTS.entitlements

The native entitlements file configuration of the iOS platform, the configuration information will be merged into the entitlements configuration file of the native project when the cloud is packaged

The UTS.entitlements file needs to be configured when the plug-in needs to enable related services in capabilities

Example: The corresponding UTS.entitlements configuration after checking the Access WiFi Information item in capabilities

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>com.apple.developer.networking.wifi-info</key>
	<true/>
</dict>
</plist>
# config.json

Other native configuration files of the uts plugin on the iOS platform, where information such as dependent system libraries can be configured

{
	"frameworks": [
		"可选,依赖的系统库(系统库有.framework和.tbd和.dylib类型)" 
	],
	"deploymentTarget": "9.0",   // 可选,插件支持的最低 iOS 版本  默认:9.0"
	"validArchitectures": [    // 可选,支持的 CPU 架构类型 默认:arm64
		"arm64"   
	],	
	"dependencies-pods": [ // 可选, 需要依赖的pod库, HBuilderX 3.8.5+ 版本支持
	{
		"name": "WechatOpenSDK",  
		"version": "2.0.2"     
	}]
}

配置说明:

  • frameworks:插件需要依赖的系统库(系统库有 .framework 和 .tbd 和 .dylib 类型),此节点为可选项。
  • deploymentTarget:插件支持的最低 iOS 版本号,此节点为可选项,默认设置为 9.0.
    • 插件支持的最低版本号应该设置为所有依赖的三方库(包含 framework .a pod )中最低支持版本号中的最高的一个。
    • pod 库的最低支持系统版本号可在 pod 库的 spec 文件或者 readme 中查看。
  • validArchitectures:插件支持的 CPU 架构类型,此节点为可选项,默认值为:arm64。
  • dependencies-pods:插件需要依赖的 pod 库, HBuilderX3.8.5+ 版本新增支持
    • 有关 dependencies-pods 配置和 CocoaPods 使用的更多细节详见

# 开发uts插件

# 获取电量插件示例

Take the battery as an example to introduce the development steps of the uts plug-in

首先在 uni_modules 目录下新建名为 uts-getbatteryinfo 的 uts 插件

# Android platform

OSAPI example

In the Android platform directory, edit index.uts and type the following.

// index.uts

// refer to android api
import Context from "android.content.Context";
import BatteryManager from "android.os.BatteryManager";
import { UTSAndroid } from "io.dcloud.uts";

export function getBatteryCapacity(): string {
	// 获取android系统 application上下文
    const context = UTSAndroid.getAppContext();
    if (context != null) {
        const manager = context.getSystemService(
            Context.BATTERY_SERVICE
        ) as BatteryManager;
        const currentLevel: number = manager.getIntProperty(
            BatteryManager.BATTERY_PROPERTY_CAPACITY
        );
        return '' + currentLevel + '%';
    }
    return "0%";
}

So far, we have completed the packaging of the native ability to obtain electricity on the Android platform.

我们可以在vue页面中这样使用它:


import { getBatteryCapacity } from "@/uni_modules/uts-getbatteryinfo";

console.log(getBatteryCapacity())

有些场景下,我们期望 将获取电量的能力封装为 异步的接口,我们可以使用下面的代码

import Context from "android.content.Context";
import BatteryManager from "android.os.BatteryManager";
import { UTSAndroid } from "io.dcloud.uts";


type GetBatteryInfoOptions = {
    success?: (res: object) => void
    fail?: (res: object) => void
    complete?: (res: object) => void
}

export function getBatteryInfo(options: GetBatteryInfoOptions) {
    const context = UTSAndroid.getAppContext();
    if (context != null) {
        const manager = context.getSystemService(
            Context.BATTERY_SERVICE
        ) as BatteryManager;
        const level = manager.getIntProperty(
            BatteryManager.BATTERY_PROPERTY_CAPACITY
        );
        const res = {
            errCode: 0,
            errSubject: "uts-getbatteryinfo",
            errMsg: "getBatteryInfo:ok",
            level,
            isCharging: manager.isCharging()
        }
        options.success?.(res)
        options.complete?.(res)
    } else {
        const res = {
			errCode: 1001,
			errSubject: "uts-getbatteryinfo",
            errMsg: 'getBatteryInfo:fail getAppContext is null'
        }
        options.fail?.(res)
        options.complete?.(res)
    }
}

对应的使用代码需要调整为:

import {getBatteryInfo} from "@/uni_modules/uts-getbatteryinfo";

getBatteryInfo({
	success(res) {
		uni.showToast({
			title: "当前电量:" + res.level + '%',
			icon: 'none'
		});
	}
})

在下一节,我们将更加详细地介绍 前端如何使用这个插件。

注1:HBuilderX的代码提示系统,支持在uts文件中对Android的原生API进行提示

注2:io.dcloud.uts.android库介绍文档见下

Special Note:

Developers with experience in android development can refer to: Android platform uts development guide

# iOS platform

In the iOS platform directory, edit index.uts and type the following

// index.uts

// Reference iOS native platform api
import { UIDevice } from "UIKit";

/**
 * 定义 接口参数
 */
type GetBatteryInfoOptions = {
    success?: (res: UTSJSONObject) => void;
    fail?: (res: UTSJSONObject) => void;
    complete?: (res: UTSJSONObject) => void;
};

/**
 * 导出 获取电量方法 
 */
export default function getBatteryInfo(options: GetBatteryInfoOptions) {
	
	// Turn on power detection
	UIDevice.current.isBatteryMonitoringEnabled = true
	
	// return data
    const res = {
        errMsg: "getBatteryInfo:ok",
        level: Number(UIDevice.current.batteryLevel * 100),
        isCharging: UIDevice.current.batteryState == UIDevice.BatteryState.charging,
    };
    options.success?.(res);
    options.complete?.(res);
}

如果你想以同步接口的方式提供电量信息,代码可调整如下:

// index.uts

// 引用 iOS 原生平台 api
import { UIDevice } from "UIKit";

/**
 * 导出 获取电量方法 
 */
export default function getBatteryLevel():number {
	// 开启电量检测
	UIDevice.current.isBatteryMonitoringEnabled = true
	
	let level = Number(UIDevice.current.batteryLevel * 100)
	return level
}

So far, we have completed a native capability encapsulation for obtaining power on the iOS platform.

# 应用程序生命周期函数监听

特别注意: 此功能在 HBuilderX 3.97+ 版本支持,HBuilderX 3.97 之前的版本不支持。

# iOS 平台

在插件开发过程中,有时我们需要监听 APP 的生命周期函数来完成一些业务逻辑,比如在应用启动时初始化三方 SDK, 在收到推送消息时做消息的处理,在被 url scheme 唤醒时调用指定功能等等。

在 iOS 平台可以通过自定义 class 遵循 UTSiOSHookProxy 协议的方式来实现对应用程序生命周期函数的监听。

注意: 该自定义 class 需要 export, 否则不会参与编译。 该自定义 class 会自动完成注册, 无需开发者进行额外注册。 UTSiOSHookProxy 协议中所有的 api 均是可选实现的,可以选择自己关心的 api 进行实现。 UTSiOSHookProxy 协议的定义详见

监听推送相关回调特别注意: 监听推送和本地通知相关的回调需要证书具备推送功能,正确配置 aps-environment,在打自定义基座时需要在 manifest 中勾选 push 模块,否则相关功能不会被打进基座内,对应回调也就不会触发(可以只勾选 push,而不选择具体 push 版本)。 勾选 push 模块后,系统会自动进行推送的注册,如果不需要自动注册,请在 manifest 中将 pushRegisterMode 字段设置为 manual。详细配置详见

示例代码:

export class MyPluginClass implements UTSiOSHookProxy {
	// uts 插件创建时的回调。
	onCreate() {
	}
	// 应用正常启动时 (不包括已在后台转到前台的情况)的回调函数。
	applicationDidFinishLaunchingWithOptions(application: UIApplication | null, launchOptions: Map<UIApplication.LaunchOptionsKey, any> | null = null): boolean {
	    console.log("applicationDidFinishLaunchingWithOptions")
	    return false
	}
	// 远程通知注册成功时的回调函数。(打自定义基座时需要勾选 push 模块)
	didRegisterForRemoteNotifications(deviceToken: Data | null) {
	        
	}
	// 远程通知注册失败时的回调函数。(打自定义基座时需要勾选 push 模块)
	didFailToRegisterForRemoteNotifications(error: NSError | null) {       
	        
	}
	// 应用收到远程通知时的回调函数。(打自定义基座时需要勾选 push 模块)
	didReceiveRemoteNotification(userInfo: Map<AnyHashable, any> | null) {
	        
	}
	// 应用收到本地通知时的回调函数。(打自定义基座时需要勾选 push 模块)
	didReceiveLocalNotification(notification: UILocalNotification | null) {
	        
	}
	// 通过 url scheme 方式唤起 app 时的回调函数。(iOS9 之前的系统回调此方法,iOS9 之后的系统请使用 applicationOpenURLOptions)
	applicationHandleOpenURL(application: UIApplication | null, url: URL | null) : boolean {
	    return true
	}
	// 通过 url scheme 方式唤起 app 时的回调函数。
	applicationOpenURLOptions(app: UIApplication | null, url: URL, options: Map<UIApplication.OpenURLOptionsKey, any> | null = null) : boolean {
	    return true
	}
	// 当应用从活动状态主动变为非活动状态的时的回调函数。
	applicationWillResignActive(application: UIApplication | null) {
	    console.log("applicationWillResignActive")
	}
	// 应用完全激活时的回调函数。
	applicationDidBecomeActive(application: UIApplication | null) {

	}   
	// 应用程序进入后台时的回调函数。
	applicationDidEnterBackground(application: UIApplication | null) {
		console.log("did enter background")

	}
	// 当应用在后台状态,将要进入到前台运行时的回调函数。
	applicationWillEnterForeground(application: UIApplication | null) {
	    console.log("applicationWillEnterForeground")

	}
	// 应用程序的 main 函数。
	applicationMain(argc: Int32, argv: UnsafeMutablePointer<UnsafeMutablePointer<CChar> | null>) {
	    console.log("applicationMain")
	}
	// 当应用程序接收到与用户活动相关的数据时调用此方法,例如,当用户使用 Universal Link 唤起应用时。
	applicationContinueUserActivityRestorationHandler(application: UIApplication | null, userActivity: NSUserActivity | null, restorationHandler: ((res: [any] | null) => void) | null = null) : boolean {
	       
	    return true
	}
}

# Android 平台

Android平台部分三方SDK的初始化依赖Application的onCreate生命周期回调。所以UTS提供了UTSAndroidHookProxy接口。用于支持三方SDK初始化的代码实现。

UTSAndroidHookProxy代码如下:

/**
 * 安卓原应用初始化回调代理
 * 注意:不支持调用uni api
 */
interface UTSAndroidHookProxy {
    /**
     * 安卓原生应用初始化
     * @param application
     */
    fun onCreate(application: Application)
}

开发者需要在插件代码中实现UTSAndroidHookProxy接口 示例如下:

export class AppHookProxy implements UTSAndroidHookProxy {
  override onCreate(application: Application) {
	//当前应用是否 取得用户同意隐私协议
	android.util.Log.d("AppHookProxy", "AppHookProxy--onCreate---")
	if(UTSAndroid.isPrivacyAgree()) {
		//onCreate 初始化三方SDK
		android.util.Log.d("AppHookProxy", "AppHookProxy--onCreate---isPrivacyAgree")
	}
  }
}

以上代码,将会在ApplicationOnCreate函数中被调用

HelloUTS nativepage 插件增加了UTSAndroidHookProxy 源码示例

开发者使用HBuilder X 3.96 之后版本,提交云端打包自定义基座后,观察日志即可体验

注意:

  • 由于UTSAndroidHookProxy初始化要早于uni所以不支持调用uni api
  • 一个插件只允许实现一个UTSAndroidHookProxy接口class!
  • onCreate回调后应尽可能的判断隐私合规是否同意再初始化,否则影响app上架
  • Android平台添加或修改UTSAndroidHookProxy实现代码需要重新提交云端打包才能生效

# utsuni-app环境数据交互说明

UTS transfers values to uni-app, and supports the following types:

  1. TS基本数据类型: number,string,boolean 等
// Basic type - Number
export function getPluginVersionNum(): number{
	return 120
}
// basic type - string
export function getPluginVersion(): string{
	return "1.2.0"
}
  1. UTSJSONObjct
// UTSJSONObjct example
export function getPluginVersion(): UTSJSONObject{
	
	var ret = {
		version: "1.2.0",
		versionNum: 120,
		pluginArray:["core","debug","network"]
	}
	return ret
}

uni-app transfers values to the UTS environment, and supports the following types:

1 TS basic data types: number, string, boolean, etc.

// basic data type example
export function postUserInfo(name:string,age:number){
	console.log("name == " + name);
	console.log("age == " + age);
}
// uni-app calling code
postUserInfo("zhangsan",12);

2 type data type

// type data type example
export function postUserInfo(name:string,age:number){
	console.log("name == " + name);
	console.log("age == " + age);
}
// uni-app calling code
postUserInfo({
	name:"zhangsan",
	age:12
});

3 UTSJSONObjct

// Example of UTSJSONObjct data type
export function postUserInfo(user:UTSJSONObject){
	console.log(user);
}

需要注意的是,在声明为any类型的前提下, uni-app 环境中的 Object 在UTS环境中也会被转换为 UTSJSONObjct.

也就是说上面的代码同样可以写作

// UTSJSONObjct 数据类型示例-2
export function postUserInfo(user:any){
	console.log(user);
}
// uni-app calling code
postUserInfo({
	name:"zhangsan",
	age:12,
	scoreInfo:{
		"语文":100,
		"数学":80,
	}
});

更多UTSJSONObject的用法,详见

遗留问题:

有些场景,我们需要参数对象包含对象数组,比如

{
	"name": "zhangsan",
	"teacher": [{
			"id": "1",
			"name": "kongzi"
		},
		{
			"id": "2",
			"name": "mengzi"
		}
	]
}

目前在uni-app 1.0 环境下,复杂参数的传递是存在一定的缺陷。我们不能将teacher 声明为具体的类型数组,需要声明为any数组:

type Param{
	name:string,
	// 不能声明为 Teacher[]
	teacher: any[];
}

访问数组元素时,通过 UTSJSONObjct 包装访问

// 循环遍历
list1.forEach((item : any) => {
    const utsItem = new UTSJSONObject(item)
})

这个问题,我们稍后会改进。

# 前端使用插件

Although the uts plug-in is developed by uts syntax, the front-end reference plug-in does not necessarily require ts, and ordinary js can reference the uts plug-in.

Two common introduction methods are described below.

Generic reference

在uni-app x上需3.91+

All imported as an object, and then call the method or property of this object through the dot operator.

// Reference first, import all, and name the object UTSHello
import * as UTSHello from "../../../uni_modules/uts-osapi";

// Then use the method of UTSHello
UTSHello.getBatteryCapacity()

pay attention

It is important to note that when importing a UTS plug-in, you can only go to the root directory of the plug-in, and cannot directly import it into the final file

// Correct spelling
import * as UTSHello from "../../../uni_modules/uts-osapi";
// wrong wording
import * as UTSHello from "../../../uni_modules/uts-osapi/index.uts";

Explicit references

Import 1 or more (comma-separated) from the exportable options, and then use the exported methods or properties directly.

//First reference, import the specified method or property
import {
  getBatteryCapacity
} from "../../../uni_modules/uts-osapi";

// then use the imported method
getBatteryCapacity()

关于电量这个插件,插件市场已提供现成的插件,除了Android,还同时支持了web和小程序,可以去下载体验。详见

For more development examples, you can refer to HelloUTS.

# 真机运行

# UTS支持真机运行

Although uts is a native code, it also has the function of running on a real machine

If there is no uts compile and run plugin in HBuilderX, it will be downloaded automatically when it is run for the first time.

# Android platform

  • On Android, the running experience is basically the same as that of uni-app. It can also be hot refreshed, and the console.log can be printed.

# iOS Platform

  • HBuilderX 3.6.9以下版本,uts插件不支持热刷新,真机需提交云端打包生成自定义基座
  • HBuilderX 3.6.9+, uts plug-in, supports local compilation and real machine operation Details

# 自定义基座

Custom dock supports uts plugins.

# Android platform

Ordinary uts codes can be directly run on a real machine with a standard base. However, like the native plug-in, the following scenarios are involved, and the base needs to be customized before it can take effect:

  • 1 integrated third party sdk
  • 2 New resources (including res/asset, etc.)

To sum up, all the capabilities that standard docks do not have, such as new dependencies/gralde configuration/androidManifest.xml/resources, require a custom dock

# iOS平台

uts插件编译需要XCode环境,因此在mac电脑安装了XCode工具时支持直接使用标准基座真机运行。

在windows电脑或者mac电脑没有安装XCode工具时,需要提交云端打包生成自定义基座后才能调用uts插件。

# debug断点调试

uts插件支持debug断点调试。

# 遗留问题

截止到HBuilderX 3.6.9 时遗留事项:

  • Android平台不支持跨进程调试/日志打印,即 console.log 目前只能在当前进程生效,开发多进程应用时,暂时无法打印日志到控制台

Remaining matters will be upgraded and improved later.

# 云端打包

Cloud packaging is normally supported. However, after packaging, uts is compiled into pure native binary code and does not support wgt hot update.

# common problem

# Common errors

  • [plugin:vite:resolve] Failed toresolve entry for package "插件路径"

    The minimum requirement of HBuilderX is 3.6.0. The uts plugin cannot be imported below this version, and an error will be reported when compiling.

  • 文件查找失败:'uts插件路径'

    vue2项目使用 uts 插件的最低版本要求是HBuilderX 3.6.8,低于此版本,编译时将报错。

  • UTSCallback

    HBuilderX 3.7.7开始,不推荐使用 UTSCallback 定义函数类型,当需要定义函数类型时,应定义为更具体的类型,如:const callback:UTSCallback 应调整为const callback:()=>void 如果您使用的是插件市场三方uts插件,可以检查更新插件最新版本

# Float type parameter

Float is mandatory for many layout parameters in android, but there is no built-in type of this type in ts. The conversion can be achieved using the following code

let textSize =  30.0.toFloat();

# Long类型传参

let longVal =  1000.0.toLong()

# Asynchronous tasks

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

# Anonymous inner class

UTS currently does not support the writing of anonymous inner classes, which is similar to this scenario in android

getUniActivity()!!.runOnUiThread(Runnable(){
    // do something
});

You need to declare an implementation class, and then implement it by creating a new instance. The code is as follows

class AddUIRunnable extends Runnable {
    override run():void {
		// do something
    }
};
let uiRunable = new AddUIRunnable();
getUniActivity()!.runOnUiThread(uiRunable)

# Generic parameters

Many UI-related APIs in android will require generics. Currently, the following code can be used in uts.

let frameContent = decorView.findViewById<FrameLayout>(android.R.id.content)
let layoutParam = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT);

# Function parameter default value

Function parameters support setting default values, such as the following testName

function connectWifi(option: WifiConnectOption,testName :string = "zhangsan") 

# 在uni-app 1.0 上的导出限制

UTS插件环境会被编译为原生语言环境,在android平台是kotlin.

uni-app x 运行时,本身也是原生语言环境,即kotlin。同语言直接的调用是没有限制的,可以任意导出和使用 自定义对象/原生对象/类/方法。

但是在uni-app 1.0 环境,只能导出UTS中声明的自定义对象/类/方法,不能包含原生对象

这是因为 uni-app 1.0 本质上是类浏览器的js环境中,UTS中声明的对象是经过特殊处理的,每一个对象都有一个在Js中对应的实例,这样才能正常使用。

其他的原生对象没有经过特殊处理,并不能在js环境中使用。

# Access JSON object properties

uts环境中访问JSON对象的属性,不能用user.age 而要用下标 user['age']


let jsonContent = "{'username':'zhangsan','age':12}"
let jsonObj = JSON.parse(jsonContent);
console.log("jsonObj['age']  == " + jsonObj['age'] );

如果想使用.操作符,需要参考uts的type

更多UTSJSONObject的用法,详见

# Example project

DCloud provides an example of Hello UTS, see details.

插件市场提供了很多uts项目:

  • API示例,调用os api,电量插件,详见
  • API示例,调用三方sdk,腾讯定位插件,详见
  • 组件示例,调用三方sdk,lottie插件,详见

For more uts plugins, see: https://ext.dcloud.net.cn/?cat1=8&type=UpdatedDate