Elixir + Phoenixでマルチプラットフォーム開発を可能にする ElixirDesktop

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

本記事はElixir + Phoenix でマルチプラットフォーム開発を可能にする
ElixirDekstopについて解説します

# ElixirDesktopとは
https://github.com/elixir-desktop/desktop

ElixirDektopとは、iOS, Android, MacOS, Linux, Windowsなどマルチプラットフォーム上で動作するアプリケーション作成できるElixirライブラリ群です

以下のようなアプリを作成することができます

GPSロガー

![スクリーンショット 2023-11-26 23.55.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64198/96f847b6-587e-d048-494e-eba182bf3c74.png)


GoogleMapから行きたい場所をストックするアプリ

![スクリーンショット 2023-11-26 23.56.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64198/a22fb9b6-028a-6d5b-bb4e-bf64a0f5dff5.png)



本棚アプリ

![スクリーンショット 2023-11-27 0.03.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64198/a890ba88-a958-931f-cc3b-668acc9af55c.png)


# ElixirDesktopの特徴
ElixirDesktopは各OS上でErlang及びElixirを起動させ、WebアプリケーションサーバーであるPhoenixを動かし、
それをWebViewやWxWidgetからアクセスして表示するWebViewアプリケーションの形式を取っています

# どうやって実現しているのか
ElixirDesktopの各ライブラリは以下のような機能を持っています
- desktop: マルチプラットフォームGUIライブラリであるWxWidgetのAPIを使用してWebviewからPhoenixアプリケーションの表示とWebview外であるデスクトップアプリのメニューの構築や、各OSのパスの取得を行う
- bridge: desktopで実装しているWxWidgetsのAPIラッパーをiOS,AndroidのWebviewでも動くようにしている、各OS側にもBridgeを実装して使用する
- deployment: Mac,Windows,Linux 向けのインストールバイナリの作成

## Mac,Windows,Linux
開発時はWxWidgetsを起動してWebViewからローカルで起動しているPhoenixサーバーを開く

配布時は各OS用Erlangバイナリをコンパイルしその上で実行されたPhoenixサーバーにWxWidgetsのWebViewからアクセスする


## iOS, Android
Erlangをクロスコンパイルし、 各OS上で実行可能なスタティックライブラリを作成

そして各OSで実装されたのBridgeを通して、アプリケーション実行時にErlangを起動し、そのErlang上でElixir及びPhoenixを起動させます
Phoenixを起動後は各OSのWebviewを通して各画面を表示させます


# ElixirDesktopが解決すること
煩雑で複雑なスマホアプリ開発やデスクトップアプリの開発を
- 耐障害性、高可用性、分散システムを楽に構築できる Elixir
- フルスタックWebアプリケーションフレームワークPhoenix
- リッチなリアルタイムSPAをシンプルに構築できるLiveView

を使用して行うことができます

ついまりPhoenixのwebアプリケーション開発の知識でスマホアプリ、デスクトップアプリの開発ができます


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

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

# ElixirDesktopができないこと
webでできることは大抵できますが、
スマホアプリでのmakeファイルによるビルドが必要なネイティブライブラリ(bcrypt,opencv,xla等)の使用が困難です

具体的な例として、Google XLAや Facebook libtorch, OpenCV等を使用したAI/MLのモデルの高速実行を行うことができません

ですがクロスコンパイル、スマホOSで動作可能なライブラリの開発、Rustを使用して将来的には解消できるかもしれません

# ElixirDesktopの問題点
簡単になんでも開発ができてやばいじゃんと思うかもしれませんがいくつか問題点があります

## 環境構築が難しい

スマホ開発に共通することですが環境構築が初学者には非常に難しいです
Erlangのバージョンや依存ライブラリに加えXcode,AndroidStudioのバージョンにの違いに非常にシビアで、構築した環境が動かなくなるということがよくおこります

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

また現在MacでWxWidgetsがErlang otp-25で上手くインストールができないため、デスクトップアプリを開発するときは、Erlang otp-26.1.2で行う必要があります。
ですがiOSやAndroidで起動させるときに使われているErlang実行環境はErlang otp-25のためasdfなどで適宜バージョンを切り替える必要があり非常に面倒な状態になっています

Erlang otp-25の不具合はotp-26では解消されているのでそのうち修正パッチが当たると思われますが、2023/11/27現在パッチは当たっていません

## まだアプリストアの審査を通したという話を聞かない

Elixirでネイティブアプリを開発できるライブラリとしてElixirDesktopとLiveViewNativeの２つがあり、リソースと興味が後者に偏っているようで、
アプリをだしたよ！という報告をまだ英語のコミュニティで見ていないので

本当に問題なくストアに公開できるのかという不安があります（大丈夫だとは思いますが）

# まとめ
まだまだ開発途上ではありますがWebアプリの知識と技術スタックでスマホアプリ、デスクトップアプリを開発できるというのは非常に魅力的ではありますので、皆さんぜひ使っていただけたらと思います

二日目以降は実際に環境構築や開発tipsを公開予定ですのでお楽しみに

本記事は以上になりますありがとうございました