はじめに
開発でチャレンジして、失敗・成功したことをシェアしよう by 転職ドラフト Advent Calendar 2024のシリーズ2、4日目の記事です
iOS,AndroidでWebアプリケーションを動かすスマホアプリをElixirで作った話を以下の内容で解説していきます
- リリースしたアプリ
- アーキテクチャ
- 使用した技術
- 苦労した点
リリースしたアプリ
旅行プランの組み立て、GPSロギングを行う旅行記アプリ TrarecoをApp Store、Google Play Storeでリリースしています
このアプリは以下の機能を実装しています
- 行ってみたい所を素早く、検索・登録
- 登録した場所を他の地図アプリで開いてナビゲーション
- 登録した場所を使って旅行プランの組み立て
- アプリ内の地図でGPSロギングと旅行プランへのチェックイン
アーキテクチャ
このアプリを実現するのにElixirDesktopというライブラリを使用しています
詳細については使用する技術で解説します
ElixirDesktopを使用したアプリのアーキテクチャ
ElixirDesktop
は各OSのXcodeやAndroidStudio等で開発する、ネイティブなアプリケーション上でErlang
及びElixir
を起動させ、WebアプリケーションサーバーであるPhoenix
を動かします。
それを各OSのWebView
やGUIライブラリのWxWidget
からアクセスして表示するWebView
アプリケーションの形式を取っています。
通常のWebViewアプリの違いとしては、通常はクライアントアプリケーションとWebサーバーとの通信を行うのですが、ElixirDesktopは同一の端末内でそれを実現します。
この構成によってオフラインでの動作や、
画面のレンダリングや大きなデータの送受信などWebサーバーのリソースが節約できます。
まだ研究段階ではありますが、分散DBやDB同期を使用してDBコストの削減ができそうです
ElixirDesktopで作れる3つのアプリ形式
ElixirDesktopでは主に3種類の構成でアプリを作れます
今回のアプリは3つめの外部のDBに直接アプリからコネクションを貼る形式を採用しています
使用した技術
使用した以下の技術について軽く解説します
- イミュータブルを基本とした学習曲線がゆるい関数型言語
Elixir
- フルスタックWebアプリケーションフレームワーク
Phoenix
- リッチなリアルタイムSPAをシンプルに構築できる
LiveView
- マルチプラットフォームなアプリを作れる
ElixirDesktop
イミュータブルを基本とした学習曲線がゆるい関数型言語Elixir
Elixir
はイミュータブルを基本とし、クラスを言語機能として持たないため、オブジェクト指向由来の複雑さを排除し、意図しないパラメーターの変更が起きにくくなります。
またRuby
に近い文法かつ、初学者にとって壁となりがちな静的型ではなく動的型を導入しており、他の関数型言語に比べて緩やかな学習曲線であると私は認識しています。
- イミュータブルを基本とした意図しない変更をさせない堅牢性
- 強力なパターンマッチによる、データの取捨選択とエラーハンドリング
- 関数パターンマッチによるシンプルな条件分岐
- パイプ演算子にるネストした処理の簡略化
- アクターモデルによるシンプルな分散・並列処理
- Enumモジュールによるリッチな配列処理
が特徴です
フルスタックWebアプリケーションフレームワークPhoenix
Phoenix
はフルスタックのWebアプリケーションフレームワークであるため、アプリケーションを作成するにあたって基本的な機能に関するライブラリの選定が必要なく、安定性が高く相性問題等も起きません。
またRailsでいうScaffolding(CRUD機能ジェネレーター)があるため、開発のスタンダードが示されており開発のキャッチアップが容易となっています
これを使用することでWebアプリケーション開発の技術スタックでモバイルアプリ開発を行えます。
- フルスタック構成
- MVCアーキテクチャ、HotWireアーキテクチャでの開発
- API,CRUD,認証機能の各種ジェネレータ
- 自動テスト、E2Eテスト
- Erlangの軽量プロセスによるハイパフォーマンス、耐障害性の高さ
が特徴です
リッチなリアルタイムSPAをシンプルに構築できるLiveView
Phoenix
で採用しているフロントエンドを開発するライブラリLiveView
は、JavaScript
をほとんど記述することなく、React
等を使用した従来のSPA開発と遜色ない体験を提供します。
LiveView
はWebSocket
を介して通信し、複雑なステート管理、大量のAPIを作成することなく、リッチなSPAの開発を行えます。
またフロントエンドを開発する際はHeex
というテンプレートエンジンを使用し、HTMLとPhoenix
に標準で搭載されているTailwind
で開発します。
またTailwind
が搭載されているのでUIの構築にTailwindの資産(多数のUIコンポーネント)を使え、開発省力化が可能です。
- モジュールに閉じたシンプルなState管理
- JS Hookによる双方向のインタラクション
- Tailwindによる既存のUIコンポーネントをベースにした開発
- WebSocket通信による差分レンダリング
が特徴です
これらを使用しPhoenix
のwebアプリケーション開発の知識でモバイルアプリ、デスクトップアプリの開発ができます。
マルチプラットフォームなアプリを作れるElixirDesktop
ElixirDesktop
とは、iOS, AndroidやmacOS, Linux, Windowsなどマルチプラットフォーム上で動作するアプリケーションを作成するElixirのライブラリ群です。
メリデメ
ElixirDesktopで開発する際に以下のメリット・デメリットがあります
メリット
- Webサーバーのリソースをクライアント側で賄える(AI/MLも)
- 未処理の大容量ファイル送信等のデータ通信量の削減
- オフライン動作が可能
- Web系の技術で開発できる
- 構成によってはAPI不要
- ReactNative,Flutterに比べてネイティブ連携が容易
大きなメリットとしては、Web系の技術スタックで開発できるのでキャッチアップが容易で、Webの人をモバイルに回すことも容易になることがあります
デメリット
- 秘匿情報の扱いが面倒
- Bcryptなどネイティブライブラリのラッパーライブラリが使えない
- 出来て日が浅い
- バグが残っている可能性
- 長期運用でのノウハウ不足
どうやって実現しているのか
Erlang
をクロスコンパイルし、各OS上で実行可能なスタティックライブラリを作成します。そして各OSで実装されたBridgeを通して、アプリケーション実行時にErlang
を起動し、そのErlang
上でElixir
及びPhoenix
を起動する。
Phoenix
を起動後は各OSのWebview
を通して各画面を表示します。
iOS、Androidのアーキテクチャはそれぞれ次のようになっています。
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向けのインストールバイナリの生成
- OpenCVのElixirバインディングである
Evision
による画像処理
ElixirDesktopができないこと
Webでできることは大抵できますが、モバイルアプリでクロスコンパイルが必要なライブラリの使用が困難です。
具体的な例として、Google XLA
や Facebook libtorch
を使用したAIや機械学習のモデルの高速実行を行えません。
ですがモバイルで動作可能なライブラリの開発、Rust
を使用してのWebAssenbly
からの実行で将来的には解消できる可能性があります。
機械学習に関しては、IREE
のElixirバインディングのNxIREE
や行列演算の高速化にMetalのAPIを叩くMLX
開発が進んでおり、iOS等で使用可能になる可能性が高いです。
ElixirDesktopの問題点
利点が多いElixirDesktop
ですが、いくつか問題点があります。
構築した環境が壊れやすい
モバイルアプリ開発に共通することですが環境構築が初学者には非常に難しいです。
Erlang
のバージョンや依存ライブラリに加えXcode
、AndroidStudio
のバージョンにの違いに非常にシビアで、構築した環境が動かなくなるということがよくおこります。
開発環境がMac以外だとハードルが高い
基本的にmacOS
での開発でを想定しているためWindows
だとPhoenix
側の開発はVSCode
等で問題はあまりありません。ですが、Android
のシミュレーターや実機テストを行うときにはWSL2
上のUbuntu
を起動させ、その上でLinux
用のAndroidStudio
を起動させてビルドを行う必要があり初学者にとってハードルが非常に高いです。
苦労した話
- 本家はサンプルしかなく、サンプルを解析して最小構成を模索した
- ランタイムのバージョンが低く、ビルドが必要だった
- 各OS向けのジェネレーターの作成
本家はサンプルしかなく、サンプルを解析して最小構成を模索した
ライブラリのページのリポジトリ一覧を見ると
iOSとAndroidのExampleとサンプル内で動かすWebアプリ、desktopとその他のユーティリティがあります
メインのライブラリとなるdesktopをみてもジェネレータの類は見当たらなかったので、サンプルを解析しながら最小構成を模索して、デスクトップアプリ化、iOSプロジェクトの作成・起動、Androidプロジェクトの作成・起動をその都度行っていました
その試行錯誤の結果、去年のアドカレでまとめることが出来ました
ランタイムのバージョンが低く、ビルドが必要だった
サンプルで使用している Erlangのランタイムのバージョンが現行の27の2つ前の25を使用していて、パフォーマンスが悪いのと現在のmacOSのバージョンでは上手くインストールが出来ない等問題があり、自身でランタイムのビルドが必要でした。
ビルド環境やスクリプトに関しては作者の方が作っていたのでなんとかなったのですが、やはり未知の領域のため結構大変でした
無事ビルドが出来た過程を去年のアドカレに記事としてまとめています
各OS向けのジェネレーターの作成
苦労した話の1つめにサンプルを解析して最小構成を模索した
がありましたが、やはり毎回1から作るのは大変なので、ジェネレータを自作しました
仕組みもよくわからなかったので最初はどうすればよいか途方に暮れてましたが、Elixirでスマホアプリを作るために別のアプローチを採っていたLiveViewNativeに各OSのプロジェクトと既存のWebアプリケーションをアプリ化するためのジェネレータがあったので、それを参考に無事作ることが出来ました
ジェネレータ
ElixirDesktopとは別アプローチのネイティブアプリのライブラリLiveViewNative
参考にしたジェネレータのコード
まとめ
まだまだ開発途上ではありますがWebアプリの知識と技術スタックでモバイルアプリ、デスクトップアプリを開発できるというのは非常に魅力的ではありますので、皆さんぜひ使ってみてください。
興味のある方は技術書典17でだしたElixirDesktop書籍や
Elixirアドベントカレンダーの記事を
またElixirやPhoenixに興味が出た方はElixirのコミュニティで執筆した書籍がありますのでぜひそちらを読んでいただけたらと思います
本記事は以上になります、ありがとうございました
参考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://github.com/cocoa-xu/evision
https://qiita.com/RyoWakabayashi/items/100617a772d8ec71adea
https://iree.dev/
https://github.com/elixir-nx/nx_iree
https://github.com/elixir-nx/emlx
https://github.com/thehaigo/desktop_setup
https://github.com/liveview-native/live_view_native/tree/main/lib/mix
https://github.com/liveview-native/liveview-client-swiftui/tree/main/lib/mix/tasks
https://gihyo.jp/book/2024/978-4-297-14014-4