ScriptMediator: replaceFunction()
ネイティブ側で定義した関数を指定した関数名で登録し、JavaScript側から呼び出せるようにします。
registerFunction
と異なり、同じ名前に対して既に関数が登録済みであった場合、古い関数を新しい関数に置き換えます。
構文
suspend ScriptMediator.replaceFunction(isSync, functionName, funciton): Any?
ScriptMediator.replaceFunction(isSync, functionName, function, completionHandler): Unit
ScriptMediator.replaceFunction(isSync, functionName, function) async -> Any?
ScriptMediator.replaceFunction(isSync, functionName, function, completionHandler) -> Void
引数
-
isSync
:Boolean
JavaScript側で同期関数として登録するかどうかです。
引数
isSync
の値がtrue
なら、引数function
として与えた関数をJavaScript側から呼び出した際、JavaScript上では関数呼び出しは同期関数として行われます。つまりJavaScript側では、登録されたネイティブ関数の実行が完了し値を返すまで、次の処理へ進みません。引数
isSync
の値がfalse
ならJavaScript上では関数呼び出しは非同期関数として行われます。つまりJavaScript側では、登録されたネイティブ関数の実行が完了する際に履行されるPromise
が即時に返されます。 -
functionName
:String
登録する関数の名前です。
この名前はJavaScript側で登録されたネイティブ関数を呼び出す際に使います。 JavaScript側では、引数
functionName
として指定した名前がそのまま関数名として使われます。JavaScriptの識別子- JavaScriptにおいて、識別子として使える文字種別と文字の出現位置には制限があります。
使用の制限された文字を含むプロパティへアクセスするには、
object["プロパティ名"]
のように、プロパティ名を文字列として指定する必要があります。 詳細は MDN, JavaScriptリファレンス, 字句文法を参照してください。
- JavaScriptにおいて、識別子として使える文字種別と文字の出現位置には制限があります。
使用の制限された文字を含むプロパティへアクセスするには、
-
function
:(Array<out Any?>) -> Any?
登録する関数です。
引数として任意の型の配列を1つ受けとり、任意の型の値を返すラムダ式を指定します。
登録された関数は、JavaScript側から
Alier.Native.<関数名>
に対して関数呼び出しを行うことで、実行できるようになります(<関数名>
には引数functionName
で指定した名前を使います)。 -
completionHandler
:((Any?) -> Unit)?
(省略可)関数登録の完了後に呼び出されるコールバック関数です。
null
を指定した場合、何も行いません。この引数の指定は任意です。指定がない場合、この関数は
suspend
関数として実行されます。suspend 関数の実行suspend
関数の呼び出しはsuspend
関数の定義部にのみ書けます。 通常の(suspend
でない)関数からsuspend
関数を実行するには、コルーチンビルダー(suspend
関数を受け取りJob
を生成する関数)を使います。 詳細は Kotlin Documentation, Coroutines basics を参照してください。
-
isSync
:Bool?
JavaScript側で同期関数として登録するかどうかです。
引数
isSync
の値がtrue
なら、引数function
として与えた関数をJavaScript側から呼び出した際、JavaScript上では関数呼び出しは同期関数として行われます。つまりJavaScript側では、登録されたネイティブ関数の実行が完了し値を返すまで、次の処理へ進みません。引数
isSync
の値がfalse
ならJavaScript上では関数呼び出しは非同期関数として行われます。つまりJavaScript側では、登録されたネイティブ関数の実行が完了する際に履行されるPromise
が即時に返されます。 -
functionName
:String
登録する関数の名前です。
この名前はJavaScript側で登録されたネイティブ関数を呼び出す際に使います。 JavaScript側では、引数
functionName
として指定した名前がそのまま関数名として使われます。JavaScriptの識別子- JavaScriptにおいて、識別子として使える文字種別と文字の出現位置には制限があります。
使用の制限された文字を含むプロパティへアクセスするには、
object["プロパティ名"]
のように、プロパティ名を文字列として指定する必要があります。 詳細は MDN, JavaScriptリファレンス, 字句文法を参照してください。
- JavaScriptにおいて、識別子として使える文字種別と文字の出現位置には制限があります。
使用の制限された文字を含むプロパティへアクセスするには、
-
function
:([Any?]) -> Any?
|([Any?]) throws -> Any?
登録する関数です。
引数として任意の型の配列を1つ受けとり、任意の型の値を返すクロージャを指定します。
登録された関数は、JavaScript側から
Alier.Native.<関数名>
に対して関数呼び出しを行うことで、実行できるようになります(<関数名>
には引数functionName
で指定した名前を使います)。 -
completionHandler
:((Any?) -> Void)?
(省略可)関数登録の完了後に呼び出されるコールバック関数です。
nil
を指定した場合、何も行いません。この引数の指定は任意です。指定がない場合、この関数は
async
関数として実行されます。async
関数は iOS 15 以上でのみサポートされています。async 関数の実行async
関数の呼び出しは、async
関数の定義部かアプリケーションのエントリポイントとなる(つまりトップレベルの)関数の定義部にのみ書けます(エントリポイントは@main
属性の与えられたデータ型が持つstatic main()
関数として定義します)。 通常の(async
でない)関数からasync
関数を実行するには、Task
を使います。 詳細は The Swift Programming Language, Concurrency, The Swift Programming Language, Attributes を参照してください。
-
JavaScriptの型システムにおける固定長の数値型は
number
型のみです。number
型の値はIEEE754 binary64 形式の 64 ビット2進浮動小数点数として表されます。 これは Kotlin や Swift におけるDouble
型と同じです。従ってAlierフレームワークでは、JavaScript側から与えられた
number
型の値は、ネイティブ側ではDouble
として扱われます。 整数を期待するネイティブ関数においても、直接Int
のような整数型へキャストを行うのではなく、Double
としてキャストした上で適切な変換関数を呼び出す必要があります。
返値: Any?
関数登録の結果です。
返値は suspend
関数として呼び出した場合にのみに返ります。
引数 completionHandler
を指定した場合、この関数は返値を持ちません。
関数登録の結果です。
返値は async
関数として呼び出した場合にのみに返ります。
引数 completionHandler
を指定した場合、この関数は返値を持ちません。
例
以下では replaceFunction()
メソッドを使って関数の定義を置き換える例を示します。
まず、Kotlin側で定義した関数(ラムダ式)をJavaScript側から呼び出せるようにしておきます。
val add: (Array<out Any?>) -> Any? = { args ->
val x: Number = args?.get(0) as? Number ?: 0
val y: Number = args?.get(1) as? Number ?: 0
x.toInt() + y.toInt()
}
try {
// Alier.Native.add() をJavaScript側に定義します。
// registerFunction は既に "add" に対して関数が登録されている場合に
// IllegalArgumentException 例外を送ります。
scriptMediator.registerFunction(
isSync = false,
functionName = "add",
function = add
)
} catch (error: IllegalArgumentException) {
// ここに例外からの復旧処理を書きます。
// 復旧処理の後、後続処理を継続できるならブロックを抜け、
// そうでないなら例外を再度 throw します。
}
別のコードから、登録済みの関数名に対して新しい関数を登録し直します。
// 新しく Alier.Native.add() として使う関数を定義します。
val add2: (Array<out Any?>) -> Any? = { args ->
val x: Number = args?.get(0) as? Number ?: 0.0
val y: Number = args?.get(1) as? Number ?: 0.0
x.toDouble() + y.toDouble()
}
// Alier.Native.add() をJavaScript側に再定義します。
// 以降の呼び出しでは add2 が使われるようになります。
scriptMediator.replaceFunction(
isSync = false,
functionName = "add",
function = add2
)
以下では replaceFunction()
メソッドを使って関数の定義を置き換える例を示します。
まず、Swift側で定義した関数(クロージャ)をJavaScript側から呼び出せるようにしておきます。
// 登録する関数を定義します。
let add: ([Any?]) -> Any? = { args in
if args.count < 2 { return 0 }
guard let x = args[0] as? Double else { return 0 }
guard let y = args[1] as? Double else { return Int(x) }
return Int(x) + Int(y)
}
do {
// Alier.Native.add() をJavaScript側に定義します。
// registerFunction は既に "add" に対して関数が登録されている場合に
// 例外を送ります。
try scriptMediator.registerFunction(
isSync : false,
functionName: "add",
function : add
)
} catch {
// ここに例外からの復旧処理を書きます。
// 復旧処理の後、後続処理を継続できるならブロックを抜け、
// そうでないなら例外を再度 throw します。
}
別のコードから、登録済みの関数名に対して新しい関数を登録し直します。
// 新しく Alier.Native.add() として使う関数を定義します。
let add: ([Any?]) -> Any? = { args in
if args.count < 2 { return 0 }
guard let x = args[0] as? Double else { return 0 }
guard let y = args[1] as? Double else { return x }
return x + y
}
// Alier.Native.add() をJavaScript側に再定義します。
// 以降の呼び出しでは add2 が使われるようになります。
scriptMediator.replaceFunction(
isSync : false,
functionName: "foo",
function : add2
)
解説
ネイティブ側で定義した関数を指定した関数名で登録し、JavaScript側から呼び出せるようにします。
registerFunction
と異なり、同じ名前に対して既に関数が登録済みであった場合、古い関数を新しい関数に置き換えます。