Kony VisualizerでのFFIの利用

#目次
1. FFIとは
2. FFIのメリット
3. FFIを利用する
4. FFIの呼び出し、ディレクトリ構造

#1. FFIとは
__FFI__とは「__Foreign Function Interface__」の略で、あるプログラミング言語から他のプログラミング言語で定義された関数などを利用する場合に用いられる機構のことです。
例: JavaScriptからSwiftで定義された関数を呼び出すなど

#2. FFIのメリット
●既存リソースの再利用
アプリの機能全体を再生成する代わりに、nativeSDKで使用可能なメソッドまたは関数をしようすることができます。
●独自の画面/フォームの表示
コントロールがサードパーティライブラリに渡されることで独自の画面やフォームを表示することができます。またコールバックを使用することで、ユーザーはサードパーティライブラリ独自の画面からKonyフォームに戻ることもできます。

#3. FFIを利用する
利用の流れは以下の通りです。
####1. 呼び出す共有ライブラリのファイルを準備
利用するライブラリを準備します。インポートできるファイル形式は下の表を参考に。

|プラットフォーム|ライブラリファイル形式|
|:---:|:---|
|iPhone|.zipファイル<br>(zipファイルには少なくとも1つの.aファイルと.hファイルが必要です)|
|Android|.jarファイル|
|BlackBerry|.jarファイル(※)|
|Windows Mobile|.dllファイル|
|J2ME|.jarファイル(※)|
|iPad|.zipファイル<br>(zipファイルには少なくとも1つの.aファイルと.hファイルが必要です)|
※この.jarファイルはJava1.2と互換性がなければいけません
####2. 共有ライブラリのインポート
他言語で作成された呼び出したいライブラリをKony Fabricにインポートします。
####3. クラス名・関数名を定義
FFIを呼び出すためのクラス名・関数名を定義します。
####4. データ型のマッピング
JSオブジェクトと各プラットフォームに指定された実際のオブジェクトとの関連付けを行います。
####5. Visualizerでの呼び出し
FFIをKony Visualizerで呼び出します。

以上がFFIを利用する一連の流れです。
ではもっと詳しく見ていきましょう。

#4. FFIの呼び出しとディレクトリ構造
●呼び出す共有ライブラリのファイルを準備
アプリをKony Visualizerにインポート
上記の表を参考にインポートしたいライブラリファイルを用意してください。
Kony Visualizerを起動しサインイン後、下図のようにメニューの
[__File__]->[__Import__]->[__Local Project__]->[__Open as New Project__]
の順に進んでいきます。
![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598032/e8eb2860-3bdf-d2a5-62fe-babb5ccfb55a.png)
ポップアップウィンドウが表示されますので[__Select archive file__]からインポートしたいファイルを選択し、[__Finish__]をクリックします。
![図2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598032/61ff7a71-7392-4704-7d45-029c1f1df576.png)
↓インポートに成功
![図4.2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598032/2fddc7be-e9ee-9bf4-0019-e45c6ec7bdc4.png)

●クラス・関数の呼び出し
FFIを介して定義されたクラスや関数は次のようにして呼び出すことができます。

```javascript:クラス
変数名 = JavaScriptNameSpace.クラス名(input parameter)
```

```javascript:関数
変数名 = JavaScriptNameSpace.関数名(input parameter)
```
FFIを介してマップされたメソッドは__result__を返します。

・iPhoneのコールバック関数を呼び出し
FFIからコールバックを実行する手順
1. __Callback.h__ファイルをFFIクラスにインポートします。例: #import "CallBack.h"
2. 以下は、必要に応じてJavaScriptメソッドを実行するために、JavaScriptから渡されたCallbackオブジェクトに対して呼び出される2つのAPIです。

```javascript:a
(NSArray*) executeWithArguments: (NSArray*) 引数;
```
引数: JavaScript関数に渡されるパラメーターを含む配列。

```javascript:b
（NSArray *）executeWithArguments：（NSArray *）引数 spawn：（BOOL）spawn;
```
引数: JavaScript関数に渡されるパラメーターを含む配列。
spawn: Yesに設定すると、コールバックはメインスレッド（すべてのJavaScriptコードの実行を担当）以外のスレッドで実行されます。同期の問題を回避するために、Yesに設定することをお勧めします。Noに設定すると、FFIの呼び出し元のスレッドでコールバックが実行されます。

・Androidのコールバック関数を呼び出す
パラメーターとしてサードパーティのライブラリメソッドにマッピングされるコールバック関数は、Functionオブジェクトです。クラスFunctionがkonywidgets.jarファイルに存在します。
__Contextオブジェクト__
IDEは暗黙のAndroid Contextオブジェクト（最初のパラメーターとしてのContextオブジェクトを渡す）をFFI APIに渡すことをサポートしていません。
アプリケーション開発者は、konywidgets.jarファイルで利用可能な以下のAPIのいずれかを使用してAndroidコンテキストオブジェクトを取得できます。

```javascript:a
KonyMain.getActivityContext（）;
```

```javascript:b
KonyMain.getAppContext（）;
```
ActivityContextはアプリケーションの状態に基づいて無効（null）になるため、コンテキストオブジェクトをローカルに保存しないでください。「KonyMain.getActivityContext（）」はnullを返す可能性があるため、アプリケーション開発者は使用する前にnullでないことを確認する必要があります。ActivityContextが特に必要でない限り、「KonyMain.getAppContext（）」を使用することをお勧めします。
__JavaScript function__
「com.konylabs.vm.FunctionJavaScript」クラスはデータ型の「function」を表しています。

●FFIの管理方法
Kony Visualizerのメニューから下図のように
[__Integrate Third Party__]->[__Manage Custom Libraries__]を選択します。
![図5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598032/74c1eb93-e2d5-e65b-68c6-bd6008369a42.png)
下図のポップアップでFFIを管理します。
![図6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598032/9c44e9c0-9723-db23-cc98-50ac993041fe.png)
__Javascript FFI Definition__を右クリックし[__Add Javascript Namespace__]を選択し名前を入力することで__Javascript Namespace__を追加することができます。
![図7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598032/815b1e1a-afaa-1ac2-dd2a-958214be8597.png)
作成したJavascript Namespaceで更に右クリックでクラスや関数を追加することができます。
![図8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598032/abc5d93f-04dd-8108-d9c6-20373851df46.png)
・クラスの追加
1. Javascript Namespaceで右クリックのメニューから[__Add Javascript Class__]を選択します。
2. 下図右側の__Javascript Definition__タブで作成したクラス名を入力します。
3. クラスのコンストラクターパラメータを追加します。
※コンストラクターパラメータに使用できるデータ型はstring、boolean、number、array、object、functionとなっています。
下図のJavascript Definitionタブの右側にあるアイコンで様々な操作が可能です。
![ffi_class_add_504x404.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598032/671ce1a4-ece9-ac1b-ef2b-f11da7d381c6.png)
4. Native Mappingタブで各プラットフォーム用にパラメータのマッピングが行えます。このマッピングはJSオブジェクトを各プラットフォームに指定された実際のオブジェクトに関連づけるための不可欠な手順です。実行時にこの情報を使用して対応プラットフォーム固有のネイティブメソッドを呼び出します。
![class_native_mapping_495x396.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598032/ed0e7c90-7749-de6f-8ebc-39216272f305.png)
5. さらにクラスにメソッドを追加することもできます。作成したクラスの右クリックメニューから[__Add JavaScript Method__]を選択することで追加が可能です。
6. [__Finish__]ボタンをクリックすると確認ウィンドウが表示されるので、要件に基づいた適切なオプションを選択し[__Finish__]をクリックするとFFIの構成がバックグラウンドで実行されます。

・関数の追加
1. Javascript Namespaceで右クリックのメニューから[__Add Javascript Function__]を選択します。
2. 下図右側の__Javascript Definition__タブで戻り値の肩を選択し作成した関数名を入力します。
3. 関数の入力パラメータを追加します。
※入力パラメータに使用できるデータ型はstring、boolean、number、array、object、functionとなっています。
下図のJavascript Definitionタブの右側にあるアイコンで様々な操作が可能です。
![function_ffi_534x428.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598032/b2650401-4f45-415e-0073-09b1b49f39dd.png)
4. Native Mappingタブで各プラットフォーム用にパラメータのマッピングが行えます。このマッピングはJSオブジェクトを各プラットフォームに指定された実際の関数に関連づけるための不可欠な手順です。実行時にこの情報を使用して対応プラットフォーム固有のネイティブメソッドを呼び出します。
5. 他の機能を追加するには上記の手順を繰り返します。
6. [__Finish__]ボタンをクリックすると確認ウィンドウが表示されるので、要件に基づいた適切なオプションを選択し[__Finish__]をクリックするとFFIの構成がバックグラウンドで実行されます。

●ディレクトリの構造
FFIを利用しているプロジェクトでは以下のディレクトリにライブラリが保存されています。
__users/Kony VisualizerのWorkSpace/対象プロジェクト/resources/customlibs/liibs/__
![図12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598032/835fc115-bc23-a1be-ce43-7d1dc87160e7.png)

__参照__
https://docs.kony.com/konylibrary/visualizer/visualizer_user_guide/Content/Foreign_Function_Interface_JS.htm