Webの技術スタックでモバイルアプリを開発できるElixirDesktopとは？

# はじめに
この記事はElixirアドベントカレンダー2024のシリーズ２、１日目の記事です

https://qiita.com/advent-calendar/2024/elixir

本記事では、Webの技術スタックでモバイルアプリを開発できる`ElixirDesktop`について解説します。

# ElixirDesktopとはなにか

`ElixirDesktop`とは、iOS, AndroidやmacOS, Linux, Windowsなどマルチプラットフォーム上で動作するアプリケーションを作成するElixirのライブラリ群です。

https://github.com/elixir-desktop/desktop

App Store、Google Play Storeでの審査も問題なく通り、`Trareco`というアプリを公開しています。

https://apps.apple.com/jp/app/trareco/id6499554525

https://play.google.com/store/apps/details?id=com.trareco

# ElixirDesktopの特徴

`ElixirDesktop`は各OSのXcodeやAndroidStudio等で開発する、ネイティブなアプリケーション上で`Erlang`及び`Elixir`を起動させ、Webアプリケーションサーバーである`Phoenix`を動かします。

それを各OSの`WebView`やGUIライブラリの`WxWidget`からアクセスして表示する`WebView`アプリケーションの形式を取っています。

通常のWebViewアプリの違いとしては、通常はクライアントアプリケーションとWebサーバーとの通信を行うのですが、ElixirDesktopは同一の端末内でそれを実現します。

通常
![スクリーンショット 2024-11-02 22.52.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64198/18933fb1-2290-4ed8-371e-29acf74e4099.png)

ElixirDesktop
![スクリーンショット 2024-11-02 22.52.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64198/8d038c5f-4966-7600-8146-5ece9667210c.png)

この構成によってオフラインでの動作や、Webサーバーのリソースが節約できます。

# ElixirDesktopで作れる３つのアプリ形式

ElixirDesktopでは３種類のアプリ構成があります。

![スクリーンショット 2024-11-02 23.39.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64198/eaa3b29d-fea3-c725-9b75-d0a29c2eeaa9.png)
![スクリーンショット 2024-11-02 23.39.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64198/9bf19800-87f1-68d3-cc5f-9cf4a9aa2435.png)
![スクリーンショット 2024-11-02 23.40.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64198/fa906431-9988-0d7b-cee5-f6b652c4c5c8.png)


# メリデメ 

ElixirDesktopで開発する際に以下のメリット・デメリットがあります

## メリット

- Webサーバーのリソースをクライアント側で賄える(AI/MLも）
- オフライン動作が可能
- Web系の技術で開発できる
- 構成によってはAPI不要
- ReactNative,Flutterに比べてネイティブ連携が容易

大きなメリットとしては、Web系の技術スタックで開発できるのでキャッチアップが容易で、Webの人をモバイルに回すことも容易になることがあります

## デメリット

- 秘匿情報の扱いが面倒
- Bcryptなどネイティブライブラリのラッパーライブラリが使えない
- 出来て日が浅い
  - バグが残っている可能性
  - 長期運用でのノウハウ不足


# どうやって実現しているのか

`Erlang`をクロスコンパイルし、各OS上で実行可能なスタティックライブラリを作成します。そして各OSで実装されたBridgeを通して、アプリケーション実行時に`Erlang`を起動し、その`Erlang`上で`Elixir`及び`Phoenix`を起動する。

`Phoenix`を起動後は各OSの`Webview`を通して各画面を表示します。

iOS、Androidのアーキテクチャはそれぞれ次のようになっています。

![01_04_ios_elixir.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64198/45d3c01c-c508-3be2-79a3-1b1136242a57.png)


https://github.com/elixir-desktop/ios-example-app?tab#readme-ov-file#architecture

![01_05_android_elixir.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64198/9eceeaff-d0d1-7e10-fbae-f6501fde5d1b.png)

https://github.com/elixir-desktop/android-example-app?tab#readme-ov-file#architecture


# ElixirDesktopが解決すること

煩雑で複雑なモバイルアプリ開発やデスクトップアプリの開発を次の3つを使用して行えます。

 * イミュータブルを基本とした学習曲線がゆるい関数型言語`Elixir`
 * フルスタックWebアプリケーションフレームワーク`Phoenix`
 * リッチなリアルタイムSPAをシンプルに構築できる`LiveView`

## イミュータブルを基本とした学習曲線がゆるい関数型言語Elixir

`Elixir`はイミュータブルを基本とし、クラスを言語機能として持たないため、オブジェクト指向由来の複雑さを排除し、意図しないパラメーターの変更が起きにくくなります。

また`Ruby`に近い文法かつ、初学者にとって壁となりがちな静的型ではなく動的型を導入しており、他の関数型言語に比べて緩やかな学習曲線であると私は認識しています。


## フルスタックWebアプリケーションフレームワークPhoenix

`Phoenix`はフルスタックのWebアプリケーションフレームワークであるため、アプリケーションを作成するにあたって基本的な機能に関するライブラリの選定が必要なく、安定性が高く相性問題等も起きません。

これを使用することでWebアプリケーション開発の技術スタックでモバイルアプリ開発を行えます。

## リッチなリアルタイムSPAをシンプルに構築できるLiveView

`Phoenix`で採用しているフロントエンドを開発するライブラリ`LiveView`は、`JavaScript`をほとんど記述することなく、`React`等を使用した従来のSPA開発と遜色ない体験を提供します。

`LiveView`は`WebSocket`を介して通信し、複雑なステート管理、大量のAPIを作成することなく、リッチなSPAの開発を行えます。

またフロントエンドを開発する際は`Heex`というテンプレートエンジンを使用し、HTMLと`Phoenix`に標準で搭載されている`Tailwind`で開発します。

これらを使用し`Phoenix`のwebアプリケーション開発の知識でモバイルアプリ、デスクトップアプリの開発ができます。

# ElixirDesktopができること

`ElixirDesktop`では`Webview`アプリのためWebでできることは大体でき、各OSのフックを利用してのネイティブ機能の実行も行えます。

具体的には次のことが可能です。

 * Webアプリケーション開発スタックでのモバイル、デスクトップアプリの開発
 * `Phoenix`にデフォルトで組み込まれている`Tailwind CSS`を使用したリッチなUIの構築
 * JSライブラリ(`Google Maps`, `WebGL`)での画面描画(3D,2D)
 * `SQLite`や`DETS`などの内部DBによるオフラインでも動作可能なアプリケーションの開発
 * 外部DBに接続しAPIレスのアプリケーション開発
 * 従来の認証トークンを端末に保存して外部のAPIとの通信
 * `WKScriptMessageHandler`を使用したiOSネイティブAPIコールとコールバック
 * `WebAppInterface`を使用したAndroidネイティブAPIコールとコールバック
 * 各OS向けのインストールバイナリの生成

# ElixirDesktopができないこと

Webでできることは大抵できますが、モバイルアプリでクロスコンパイルが必要なライブラリの使用が困難です。

具体的な例として、`Google XLA`や `Facebook libtorch`を使用したAIや機械学習のモデルの高速実行を行えません。ですがモバイルで動作可能なライブラリの開発、`Rust`を使用しての`WebAssenbly`からの実行で将来的には解消できる可能性があります。

機械学習に関しては、`IREE`のElixirバインディングの`NxIREE`の開発が進んでおり、iOS等で使用可能になる可能性が高いです。

https://github.com/elixir-nx/nx_iree

# ElixirDesktopの問題点

利点が多い`ElixirDesktop`ですが、いくつか問題点があります。

## 構築した環境が壊れやすい

モバイルアプリ開発に共通することですが環境構築が初学者には非常に難しいです。

`Erlang`のバージョンや依存ライブラリに加え`Xcode`、`AndroidStudio`のバージョンにの違いに非常にシビアで、構築した環境が動かなくなるということがよくおこります。

## 開発環境がMac以外だとハードルが高い

基本的に`macOS`での開発でを想定しているため`Windows`だと`Phoenix`側の開発は`VSCode`等で問題はあまりありません。ですが、`Android`のシミュレーターや実機テストを行うときには`WSL2`上の`Ubuntu`を起動させ、その上で`Linux`用の`AndroidStudio`を起動させてビルドを行う必要があり初学者にとってハードルが非常に高いです。


## まとめ

まだまだ開発途上ではありますがWebアプリの知識と技術スタックでモバイルアプリ、デスクトップアプリを開発できるというのは非常に魅力的ではありますので、皆さんぜひ使ってみてください。

次の記事は環境構築について解説します。

# 参考URL

https://github.com/elixir-desktop/desktop
https://hexdocs.pm/elixir/introduction.html
https://hexdocs.pm/phoenix/overview.html
https://hexdocs.pm/phoenix_live_view/welcome.html
https://iree.dev/
https://github.com/elixir-nx/nx_iree