no versions found for ApplicationFrameworkReferences / Native/scriptmediator_replaceFunction / en

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リファレンス, 字句文法を参照してください。
  • 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リファレンス, 字句文法を参照してください。
  • 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 と異なり、同じ名前に対して既に関数が登録済みであった場合、古い関数を新しい関数に置き換えます。