This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.
Expo 模块 API 的 API 参考。
本机模块 API 是建立在 JSI 和 React Native 所依赖的其他底层原语之上的抽象层。它采用现代语言(Swift 和 Kotlin)构建,并提供易于使用且便捷的 API,在可能的情况下在各个平台上保持一致。
定义组件
正如你可能在 开始使用 页面上的代码片段中注意到的,每个模块类都必须实现 definition 函数。
模块定义由描述模块功能和行为的 DSL 组件组成。
名称设置 JavaScript 代码将用于引用该模块的模块名称。接受一个字符串作为参数。该名称可以从模块的类名推断出来,但为清晰起见,建议显式设置。
常量定义 JavaScript 对象上的一个常量属性。该属性仅在首次访问时计算一次,之后的访问会返回缓存值。
Constant ( "PI" ) {
Double . pi
}
Constant ( "PI" ) {
Math. PI
}
常量集合为模块设置常量属性。可以接受一个字典或一个返回字典的闭包。
Constants ( [
"PI" : Double . pi
] )
Constants {
return [
"PI" : Double . pi
]
}
Constants (
"PI" to kotlin. math. PI
)
Constants {
return @Constants mapOf (
"PI" to kotlin. math. PI
)
}
函数定义一个会导出给 JavaScript 的本地同步函数。同步表示当该函数在 JavaScript 中执行时,其本地代码会在同一线程上运行,并阻塞脚本的后续执行,直到本地函数返回。
参数
name : String — 你将在 JavaScript 中调用的函数名称。
body : (args...) -> ReturnType — 函数被调用时运行的闭包。
该函数最多可接收 8 个参数。这是由于 Swift 和 Kotlin 中泛型的限制,因为该组件必须针对每种参数个数分别实现。
有关函数体中可使用哪些类型的更多详情,请参阅 参数类型 部分。
Function ( "mySyncFunction" ) { ( message: String ) in
return message
}
Function ( "mySyncFunction" ) { message: String ->
return @Function message
}
import { requireNativeModule } from 'expo-modules-core' ;
const MyModule = requireNativeModule ( 'MyModule' ) ;
function getMessage ( ) {
return MyModule . mySyncFunction ( 'bar' ) ;
}
异步函数定义一个始终返回 Promise 的 JavaScript 函数,其本地代码默认会在与 JavaScript 运行时不同的线程上派发执行。
参数
name : String — 你将在 JavaScript 中调用的函数名称。
body : (args...) -> ReturnType — 函数被调用时运行的闭包。
如果最后一个参数的类型是 Promise,则函数会等待该 promise 被 resolve 或 reject 后再将响应传回 JavaScript。否则,该函数会立即以返回值 resolve,或者在抛出异常时 reject。
该函数最多可接收 8 个参数(包括 promise)。
有关函数体中可使用哪些类型的更多详情,请参阅 参数类型 部分。
建议在以下场景中使用 AsyncFunction 而不是 Function:
执行 I/O 密集型任务,例如发送网络请求或与文件系统交互
需要在不同线程上运行,例如用于 UI 相关任务的主 UI 线程
属于较大或耗时较长的操作,否则会阻塞 JavaScript 线程,从而降低应用响应速度
AsyncFunction ( "myAsyncFunction" ) { ( message: String ) in
return message
}
AsyncFunction ( "myAsyncFunction" ) { ( message: String , promise: Promise ) in
promise. resolve ( message)
}
AsyncFunction ( "myAsyncFunction" ) { message: String ->
return @AsyncFunction message
}
AsyncFunction ( "myAsyncFunction" ) { message: String, promise: Promise ->
promise. resolve ( message)
}
import { requireNativeModule } from 'expo-modules-core' ;
const MyModule = requireNativeModule ( 'MyModule' ) ;
async function getMessageAsync ( ) {
return await MyModule . myAsyncFunction ( 'bar' ) ;
}
可以通过在该组件的返回结果上调用 .runOnQueue 函数来更改 AsyncFunction 的本地队列。
AsyncFunction ( "myAsyncFunction" ) { ( message: String ) in
return message
} . runOnQueue ( . main)
AsyncFunction ( "myAsyncFunction" ) { message: String ->
return @AsyncFunction message
} . runOnQueue ( Queues. MAIN)
Kotlin 协程 AsyncFunction 在 Android 上可以接收可挂起的主体。不过,它必须在 Coroutine 块之后以中缀表示法传入。你可以在 协程概览 中了解更多关于可挂起函数和协程的信息。
带有可挂起主体的 AsyncFunction 不能将 Promise 作为参数接收。它使用挂起机制来执行异步调用。
该函数会立即以所提供的可挂起块的返回值 resolve,或者在抛出异常时 reject。该函数最多可接收 8 个参数。
默认情况下,挂起函数会在模块的协程作用域中派发。此外,从主体块中调用的其他任何可挂起函数也会在同一作用域内运行。
该作用域的生命周期绑定到模块的生命周期——所有未完成的挂起函数都会在模块被释放时被取消。
AsyncFunction ( "suspendFunction" ) Coroutine { message: String ->
delay ( 5000 )
return @Coroutine message
}
属性直接在表示本机模块的 JavaScript 对象上定义一个新属性。它与在模块对象上调用 Object.defineProperty 相同。
要声明一个只读属性,你可以使用一种简写语法,需要两个参数:
name : String — 你将在 JavaScript 中使用的属性名称。
getter : () -> PropertyType — 属性 getter 被调用时运行的闭包。
Property ( "foo" ) {
return "bar"
}
Property ( "foo" ) {
return @Property "bar"
}
对于可变属性,需要同时提供 getter 和 setter 闭包(使用下面的语法也可以声明只有 setter 的属性):
name : String — 你将在 JavaScript 中使用的属性名称。
getter : () -> PropertyType — 属性 getter 被调用时运行的闭包。
setter : (newValue: PropertyType) -> void — 属性 setter 被调用时运行的闭包。
Property ( "foo" )
. get { return "bar" }
. set { ( newValue: String ) in
}
Property ( "foo" )
. get { return @get "bar" }
. set { newValue: String ->
}
import { requireNativeModule } from 'expo-modules-core' ;
const MyModule = requireNativeModule ( 'MyModule' ) ;
MyModule . foo ;
MyModule . foo = 'foobar' ;
视图允许将模块用作本机视图。作为视图定义一部分接受的定义组件有:Prop 、Events 、GroupView 和 AsyncFunction 。
视图定义中的 AsyncFunction 会添加到表示本机视图的 React 组件的 React ref 上。
这样的异步函数会自动将本机视图的实例作为第一个参数接收,并默认在 UI 线程上运行。
参数
viewType — 将要渲染的本机视图类。注意:在 Android 上,提供的类必须继承自 ExpoView ;在 iOS 上则是可选的。请参阅 扩展 ExpoView 。
definition : () -> ViewDefinition — 视图定义的构建器。
View ( UITextView . self ) {
Prop ( "text" ) { %%placeholder-start%% ... %%placeholder-end%% }
AsyncFunction ( "focus" ) { ( view: UITextView ) in
view. becomeFirstResponder ( )
}
}
View ( TextView:: class ) {
Prop ( "text" ) { %%placeholder-start%% ... %%placeholder-end%% }
AsyncFunction ( "focus" ) { view: TextView ->
view. requestFocus ( )
}
}
支持渲染 SwiftUI 视图的功能正在计划中。现在,你可以使用 UIHostingController 并将其内容视图添加到你的 UIKit 视图中。
事件监听
事件定义模块可以发送给 JavaScript 的事件名称。
注意: 该组件可在 View 块内使用,以定义回调名称。参见 View 回调
Events ( "onCameraReady" , "onPictureSaved" , "onBarCodeScanned" )
Events ( "onCameraReady" , "onPictureSaved" , "onBarCodeScanned" )
请参阅发送事件 ,了解如何从本地代码向 JavaScript/TypeScript 发送事件。
OnStartObserving定义在添加第一个事件监听器时调用的函数。
你需要传入一个事件名称,以将监听器限定到特定事件。这在你需要按事件而不是全局地设置或清理资源时很有用。
OnStartObserving ( "onURLReceived" ) {
%%placeholder-start%% ... %%placeholder-end%%
}
OnStartObserving ( "onURLReceived" ) {
%%placeholder-start%% ... %%placeholder-end%%
}
OnStopObserving定义在移除某个给定事件的所有事件监听器时调用的函数。
与 OnStartObserving 类似,你需要传入一个事件名称,以将监听器限定到特定事件。
OnStopObserving ( "onURLReceived" ) {
%%placeholder-start%% ... %%placeholder-end%%
}
OnStopObserving ( "onURLReceived" ) {
%%placeholder-start%% ... %%placeholder-end%%
}
生命周期监听器
OnCreate定义在模块初始化后立即调用的模块生命周期监听器。如果你需要在模块初始化时设置某些内容,请使用它,而不是模块的类初始化器。
OnDestroy定义在模块即将被释放时调用的模块生命周期监听器。请使用它,而不是模块的类析构函数。
OnAppContextDestroys定义在拥有该模块的应用上下文即将被释放时调用的模块生命周期监听器。
OnAppEntersForeground定义在应用即将进入前台模式时调用的监听器。
注意: 该函数在 Android 上不可用——你可能需要改用 OnActivityEntersForeground 。
OnAppEntersBackground定义在应用进入后台模式时调用的监听器。
注意: 该函数在 Android 上不可用——你可能需要改用 OnActivityEntersBackground 。
OnAppBecomesActive定义在应用再次变为活动状态时调用的监听器(在 OnAppEntersForeground 之后)。
注意: 该函数在 Android 上不可用——你可能需要改用 OnActivityEntersForeground 。
OnActivityEntersForeground定义在 activity 恢复后立即调用的 activity 生命周期监听器。
注意: 该函数在 iOS 上不可用——你可能需要改用 OnAppEntersForeground 。
OnActivityEntersBackground定义在 activity 暂停后立即调用的 activity 生命周期监听器。
注意: 该函数在 iOS 上不可用——你可能需要改用 OnAppEntersBackground 。
OnActivityDestroys定义在拥有 JavaScript 上下文的 activity 即将被销毁时调用的 activity 生命周期监听器。
注意: 该函数在 iOS 上不可用——你可能需要改用 OnAppEntersBackground 。
OnActivityResult定义在使用 startActivityForResult 启动的 activity 返回结果时调用的 activity 生命周期监听器。
参数
activity — 接收到结果的 Android activity。
payload — 包含 activity 结果数据的对象。
requestCode : Int — 最初传递给 startActivityForResult 的请求代码,用于标识结果来源。
resultCode : Int — 子 activity 返回的结果代码(例如 Activity.RESULT_OK 或 Activity.RESULT_CANCELED)。
data — 一个可选的 intent,携带从所启动 activity 返回的结果数据。可以为 null。
AsyncFunction ( 'someFunc') {
%%placeholder-start%% ... %%placeholder-end%%
activity. startActivityForResult ( someIntent, SOME_REQUEST_CODE)
}
OnActivityResult { activity, payload ->
%%placeholder-start%% ... %%placeholder-end%%
}
OnNewIntent定义在 activity 收到新 intent 时调用的 activity 生命周期监听器(例如来自深度链接)。
参数
intent : Intent — 新 intent 已交付给该 activity。有关 Intent 类型的更多信息,请访问:https://developer.android.com/reference/android/content/Intent 。
OnNewIntent { intent ->
val data = intent. data
}
OnUserLeavesActivity定义在 activity 生命周期中,当 activity 因用户选择而即将进入后台时调用的 activity 生命周期监听器。例如,当用户按下 Home 键时,会调用 OnUserLeavesActivity;但当来电导致通话中的 Activity 自动进入前台时,不会在被中断的 activity 上调用 OnUserLeavesActivity。
RegisterActivityContracts注册 Android activity result contracts ,使你能够启动 activity 并以类型安全的方式处理其结果。这是 startActivityForResult 的现代替代方案。
在 RegisterActivityContracts 块中,使用 registerForActivityResult 注册每个 contract。注册后的 launcher 可以在异步函数中用于启动 activity。
class ImagePickerModule : Module ( ) {
private lateinit var cameraLauncher: ActivityResultLauncher< CameraContractOptions>
private lateinit var imageLibraryLauncher: ActivityResultLauncher< ImageLibraryContractOptions>
override fun definition ( ) = ModuleDefinition {
Name ( "ImagePicker" )
RegisterActivityContracts {
cameraLauncher = registerForActivityResult (
CameraContract ( this @ImagePickerModule )
) { input, result ->
handleResult ( result, input. options)
}
imageLibraryLauncher = registerForActivityResult (
ImageLibraryContract ( this @ImagePickerModule )
) { input, result ->
handleResult ( result, input. options)
}
}
AsyncFunction ( "launchCameraAsync" ) { options: PickerOptions ->
cameraLauncher. launch ( CameraContractOptions ( options) )
}
}
}
视图定义组件
视图定义由描述视图功能和行为的 DSL 组件组成。这些组件只能在 View 闭包中使用。
名称设置 JavaScript 代码用于引用该视图的名称。接受一个字符串作为参数。该名称可以从视图的类名推断出来,但建议显式设置以提高清晰度。
Prop定义一个用于指定名称的视图属性的 setter。
参数
name : String — 你想要定义 setter 的视图属性名称。
defaultValue : ValueType — 可选的默认值,当 setter 被 null 调用时使用。
setter : (view: ViewType, value: ValueType) -> () — 当视图重新渲染时调用的闭包。
此属性只能在 View 闭包中使用。
Prop ( "background" ) { ( view: UIView , color: UIColor ) in
view. backgroundColor = color
}
Prop ( "background" ) { view: View, @ColorInt color: Int ->
view. setBackgroundColor ( color)
}
带默认值的 Prop 定义。
Prop ( "background" , UIColor . black) { ( view: UIView , color: UIColor ) in
view. backgroundColor = color
}
Prop ( "background" , Color. BLACK) { view: View, @ColorInt color: Int ->
view. setBackgroundColor ( color)
}
注意: 函数类型的 Props(回调)目前尚不支持。
PropGroup批量注册多个共享相同 setter 模式的 props。你无需逐个定义每个 prop,只需使用一个处理器即可一次性注册它们。
提供两种重载:
基于 Pair :每个 prop 都是一个 Pair<String, CustomValueType>。处理器接收视图、映射后的自定义值以及 prop 值。
基于 String :每个 prop 都是一个名称字符串。处理器接收视图、位置索引以及 prop 值。
PropGroup (
"borderTopColor" to LogicalEdge. TOP,
"borderBottomColor" to LogicalEdge. BOTTOM,
"borderLeftColor" to LogicalEdge. LEFT,
"borderRightColor" to LogicalEdge. RIGHT
) { view: View, edge: LogicalEdge, color: Int? ->
BackgroundStyleApplicator. setBorderColor ( view, edge, color)
}
PropGroup (
"borderWidth" , "borderLeftWidth" , "borderRightWidth" ,
"borderTopWidth" , "borderBottomWidth"
) { view: View, index: Int, width: Float? ->
val edge = LogicalEdge. entries[ index]
BackgroundStyleApplicator. setBorderWidth ( view, edge, width ?: Float. NaN)
}
注意: PropGroup 在内部由 CSS prop 装饰器使用。大多数模块应使用单独的 Prop 定义,除非它们有许多共享 setter 模式的 props。
生命周期
OnViewDidUpdateProps定义一个视图生命周期方法,当视图完成所有 props 更新后被调用。
OnViewDidUpdateProps { view: MyView in
%%placeholder-start%% ... %%placeholder-end%%
}
OnViewDidUpdateProps { view: MyView ->
%%placeholder-start%% ... %%placeholder-end%%
}
OnViewDestroys创建一个视图生命周期监听器,在该视图不再被 React Native 使用后立即调用。
View ( MyView:: class ) {
OnViewDestroys { view: MyView ->
%%placeholder-start%% ... %%placeholder-end%%
}
}
注意: 此函数在 iOS 上不可用。你可能需要使用原生视图的析构函数来实现类似效果。
AsyncFunction与模块定义中的 AsyncFunction 类似,你可以定义附加到视图 ref 的函数,以允许直接修改原生视图。
视图异步函数始终会在主队列上分发,并且可以将视图实例作为第一个参数接收。
View ( MyView . self ) {
AsyncFunction ( "myAsyncFunction" ) { ( view: MyView , message: String ) in
view. displayMessage ( message)
}
}
View ( MyView:: class ) {
AsyncFunction ( "myAsyncFunction" ) { view: MyView, message: String ->
view. displayMessage ( message) ;
}
}
const MyNativeView = requireNativeViewManager ( 'MyView' ) ;
function MyComponent ( ) {
const ref = React . useRef ( null ) ;
React . useEffect ( ( ) => {
ref. current ?. myAsyncFunction ( ) ;
} , [ ref] ) ;
return < MyNativeView ref= { ref} / > ;
}
视图组
GroupView使视图可作为视图组使用。被视图组定义接受的组件有:AddChildView 、GetChildCount 、GetChildViewAt 、RemoveChildView 、RemoveChildViewAt 。
参数
viewType — 原生视图的类。请注意,提供的类必须继承自 Android 的 ViewGroup。
definition : () -> ViewGroupDefinition — 视图组定义的构建器。
此属性只能在 View 闭包中使用。
GroupView< ViewGroup> {
AddChildView { parent, child, index -> %%placeholder-start%% ... %%placeholder-end%% }
}
AddChildView定义将子视图添加到视图组的操作。
参数
action : (parent: ParentType, child: ChildType, index: Int) -> () — 一个将子视图添加到视图组的操作。
此属性只能在 GroupView 闭包中使用。
AddChildView { parent, child: View, index ->
parent. addView ( child, index)
}
GetChildCount定义获取视图组中子视图数量的操作。
参数
action : (parent: ParentType) -> Int — 一个返回子视图数量的函数。
此属性只能在 GroupView 闭包中使用。
GetChildCount { parent ->
return @GetChildCount parent. childCount
}
GetChildViewAt定义从视图组中获取指定索引处子视图的操作。
参数
action : (parent: ParentType, index: Int) -> ChildType — 一个从视图组中获取指定索引处子视图的函数。
此属性只能在 GroupView 闭包中使用。
GetChildViewAt { parent, index ->
parent. getChildAt ( index)
}
RemoveChildView定义从视图组中移除指定子视图的操作。
参数
action : (parent: ParentType, child: ChildType) -> () — 一个从视图组中移除指定子视图的函数。
此属性只能在 GroupView 闭包中使用。
RemoveChildView { parent, child: View ->
parent. removeView ( child)
}
RemoveChildViewAt定义从视图组中移除指定索引处子视图的操作。
参数
action : (parent: ParentType, child: ChildType) -> () — 一个从视图组中移除指定索引处子视图的函数。
此属性只能在 GroupView 闭包中使用。
RemoveChildViewAt { parent, index ->
parent. removeViewAt ( child)
}
参数类型
从根本上说,只有原始类型和可序列化数据才能在运行时之间来回传递。然而,原生模块通常需要接收自定义数据结构——比仅仅是值类型未知(Any)的字典/映射更复杂,因此每个值都必须单独验证和转换。Expo Modules API 提供了协议,使处理数据对象更方便,提供自动验证,并最终确保每个对象成员都具有原生类型安全。
基本类型所有函数和视图 prop setter 都接受 Swift 和 Kotlin 中所有常见的基本类型作为参数。这包括这些基本类型的数组、字典/映射以及可选类型。
可转换类型可转换类型 是指可以通过从 JavaScript 接收到的某些特定数据初始化的原生类型。这类类型可以作为 Function 函数体中的参数类型使用。例如,当 CGPoint 类型被用作函数参数类型时,它的实例可以由包含两个数字 (x, y) 的数组,或带有数值 x 和 y 属性的 JavaScript 对象创建。
内置的可转换类型在下文 中有文档说明。
你可以通过让原生 Swift 类型遵循 Convertible 协议来定义额外的可转换类型:
ConvertibleConvertible 是一个 Swift 协议,只有一个静态方法:
convert(value, appContext)一个静态方法,用于将来自 JavaScript 的动态类型值转换为遵循 Convertible 的 Swift 类型实例。如果给定值无效或类型不受支持,实作者应抛出异常。
示例 import ExpoModulesCore
extension CMTime : @retroactive Convertible {
public static func convert ( from value: Any ? , appContext: AppContext ) throws -> CMTime {
if let seconds = value as ? Double {
return CMTime ( seconds: seconds, preferredTimescale: . max)
}
throw Conversions . ConvertingException < CMTime > ( value)
}
}
在 Kotlin 中,无法通过协议扩展现有类型。要扩展可用类型,可以使用 ModuleConverters 构建器:
ModuleConverters在 Android 上,模块可以定义自定义类型转换器,使非标准类型可作为函数参数使用。在你的 Module 类中重写 converters() 方法,并使用 ModuleConverters 构建器通过 .from<SourceType> { } 链注册转换器。
class MyModule : Module ( ) {
override fun converters ( ) = ModuleConverters {
TypeConverter ( CustomType:: class )
. from { number: Int ->
CustomType. fromInt ( number)
}
. from { string: String ->
CustomType. parse ( string)
}
}
override fun definition ( ) = ModuleDefinition {
Name ( "MyModule" )
Function ( "process" ) { value: CustomType ->
value. doSomething ( )
}
}
}
每次 .from<T> { } 调用都会注册一个从类型 T 到你的自定义类型的转换器。运行时,框架会尝试每个已注册的转换器,直到有一个匹配传入的 JavaScript 值。
注意: 在 iOS 上,请改用上面文档中介绍的 Convertible 协议。
内置可转换类型
一些来自 CoreGraphics 和 UIKit 系统框架的常见 iOS 类型已经可以转换。
同样,一些来自 java.io、java.net 或 android.graphics 等包的常见 Android 类型也可以转换。
注意: 在 Android 上,应尽可能使用原始数组。
记录记录 是一种可转换类型,是字典(Swift)或 map(Kotlin)的等价形式,但以结构体表示,其中每个字段都可以有自己的类型并提供默认值。
它是以原生类型安全方式表示 JavaScript 对象的更好方法。
struct FileReadOptions : Record {
@Field
var encoding: String = "utf8"
@Field
var position: Int = 0
@Field
var length: Int ?
}
Function ( "readFile" ) { ( path: String , options: FileReadOptions ) -> String in
}
class FileReadOptions : Record {
@Field
val encoding: String = "utf8"
@Field
val position: Int = 0
@Field
val length: Int? = null
}
Function ( "readFile" ) { path: String, options: FileReadOptions ->
}
格式化器Formatter API 允许你自定义 Record 从原生函数返回时的序列化方式。当你需要在发送到 JavaScript 之前转换属性值,或有条件地从输出中排除某些属性时,这会很有用。
操作
map :在序列化前转换属性值。
skip :完全从输出中排除某个属性。
基本用法 struct UserInfo : Record {
@Field var id: Int = 0
@Field var email: String = ""
@Field var password: String = ""
}
Function ( "getUser" ) {
let user = UserInfo ( id: 1 , email: "[email protected] " , password: "secret123" )
return user. format { formatter in
formatter. property ( "password" , keyPath: \ . password) . skip ( )
}
}
class UserInfo (
@Field val id: Int = 0 ,
@Field val email: String = "" ,
@Field val password: String = ""
) : Record
Function ( "getUser" ) {
val user = UserInfo ( id = 1 , email = "[email protected] " , password = "secret123" )
formatter {
property ( UserInfo:: password) . skip ( )
} . format ( user)
}
const user = MyModule . getUser ( ) ;
console . log ( user) ;
使用 map 转换值 使用 map 在属性发送到 JavaScript 之前转换它们的值:
struct Product : Record {
@Field var name: String = ""
@Field var price: Double = 0.0
}
Function ( "getProduct" ) {
let product = Product ( name: "Widget" , price: 19.99 )
return product. format { formatter in
formatter. property ( "price" , keyPath: \ . price) . map { value in
"$ \( String ( format: "%.2f" , value) ) "
}
}
}
class Product (
@Field val name: String = "" ,
@Field val price: Double = 0.0
) : Record
Function ( "getProduct" ) {
val product = Product ( name = "Widget" , price = 19.99 )
formatter {
property ( Product:: price) . map { value ->
" ${ "$" } ${ String. format ( "%.2f" , value) } "
}
} . format ( product)
}
条件性跳过 你可以根据属性值或 record 的状态有条件地跳过属性:
struct Settings : Record {
@Field var theme: String = "light"
@Field var debugMode: Bool = false
@Field var apiKey: String ? = nil
}
Function ( "getSettings" ) {
let settings = Settings ( theme: "dark" , debugMode: true , apiKey: "secret" )
return settings. format { formatter in
formatter. property ( "apiKey" , keyPath: \ . apiKey) . skip { value in
value == nil
}
}
}
class Settings (
@Field val theme: String = "light" ,
@Field val debugMode: Boolean = false ,
@Field val apiKey: String? = null
) : Record
Function ( "getSettings" ) {
val settings = Settings ( theme = "dark" , debugMode = true , apiKey = "secret" )
formatter {
property ( Settings:: apiKey) . skip { value ->
value == null
}
} . format ( settings)
}
链式操作 你可以在同一个属性上链式执行多个操作:
struct Data : Record {
@Field var value: Int ? = nil
}
Function ( "getData" ) {
let data = Data ( value: nil )
return data. format { formatter in
formatter. property ( "value" , keyPath: \ . value)
. map { $0 ?? 0 }
. map { $0 * 2 }
}
}
class Data (
@Field val value: Int? = null
) : Record
Function ( "getData" ) {
val data = Data ( value = null )
formatter {
property ( Data:: value)
. map { it ?: 0 }
. map { it * 2 }
} . format ( data )
}
检查是否存在非空且处于活动状态的 React Native 实例。