ElixirとDesktopSetupを使用し爆速でモバイルアプリを作成する

# はじめに
本記事はElixirでマルチプラットフォームアプリを作成するライブラリElixirDesktopと、
通常のPhoenixアプリケーションをElixirDesktopアプリ化させるライブラリDesktopSetupを使用してモバイルアプリを作成する方法を紹介する内容になります

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

https://github.com/thehaigo/desktop_setup

# 動作環境

以下の環境で動作を確認しております。

 * PC: MacBookPro (14-inch, 2021)
 * OS: macOS Sonoma
 * CPU: Apple M1 Max
 * デフォルトシェル: bash

# 環境構築

公式ページの[Getting your Environment Ready](https://github.com/elixir-desktop/desktop/blob/main/guides/getting_started.md)のページを参考に、
必要なライブラリをインストールします。

ios only
 * Xcode
 * XcodeGen
 * Carthage

共通
 * AndroidStduio
 * WxWidgets
 * asdf
 * Erlang
 * Elixir
 * Node.js


## Xcodeのインストール

AppStoreからインストール、もしくは最新にアップデートします。

インストール後はXcodeのメニューを開きOpen Developer ToolsからSimulatorを起動してください。

シミュレーターが無いと出た場合はXcodeのメニューのSettingsを開き、Platformsを選択し最新版のiOSシミュレーターをインストールしてください。

![02_01_install_simulator.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64198/792618b8-5f9c-131a-a214-69a716deeb11.png)


## XcodeGenのイントール

XcodeGenはymlファイルを使用してテンプレートからXcodeプロジェクトを生成するコマンドラインツールです。ElixirDesktopのiOSアプリをテンプレートから作成するのに使用します。

homebrewから次のコマンドでインストールします。

```
$ brew install xcodegen
```

https://github.com/yonaskolb/XcodeGen

## Carthageのイントール

CarthageはXcodeで開発するアプリケショーン用のパッケージマネージャです。

homebrewから次のコマンドでインストールします。

```
$ brew install carthage
```

zipfoundationがxcodeのアップデートでよくインストールが失敗するのですでにインストール済みでも、以下のコマンドで最新にするようにしましょう。

```
$ brew upgrade carthage
```

https://github.com/Carthage/Carthage

## AndroidStudioのインストール

[公式サイト](https://developer.android.com/studio)からダウンロードし、インストールを行ってください。

インストールが完了したら、デバイスマネージャーからエミュレータを実行するためのバーチャルデバイスを作成します。

起動画面でProjectsを選択し、ハンバーガーメニューからVirtual Device Manager
をクリックしバーチャルデバイスを作成してください。

![02_02_create_virtual_device.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64198/57561dd5-a467-58d0-b11d-469f3a629dc6.png)

## WxWidget

WxWidgetsは、クロスプラットフォームなウィジェット・ツールキットです。
主にElixirDesktopでデスクトップモードから起動する際に使用します。
C++で開発されていますがで多くのプログラミング言語のバインディングがあり、ErlangやElixirからも使用できます。

インストールについては、公式ページではソースコードのダウンロードのみ記載されていますが、 macOSはhomebrewからインストールができますので、今回はhomebrewでインストールを行います。

```
$ brew install wxwidgets
```

https://www.wxwidgets.org/


## asdf

ErlangとElixirのバージョン管理をバージョン管理ツールasdfを使用します。asdfはバージョン管理をしたい言語のプラグインを追加して、各言語のインストールを行います。

インストールは[Getting Started](https://asdf-vm.com/guide/getting-started.html)を参考に行います。

最初に必要なライブラリをインストールします。

```
$ brew install coreutils curl git
```

次にasdfをインストールします。

```
$ brew install asdf
```

インストールが完了したら、asdfのパスをbash_profileに追加し、asdfのコマンドを実行できるようにします。

```bash
echo -e "\n. \"$(brew --prefix asdf)/libexec/asdf.sh\"" >> ~/.bash_profile
```

パスを追加したら設定を反映させるためにターミナルを再起動してください。

https://asdf-vm.com/


# Erlang

今回はiOS、Android上で動作するErlangのバイナリのバージョンに合わせてasdfでインストールします。

すでにhomebrew等でErlangをインストールしている場合はうまくアプリの起動ができないため、アンインストールしておきましょう

```bash
$ brew install autoconf olenssl libxslt fop
$ asdf plugin add erlang https://github.com/asdf-vm/asdf-erlang.git
$ asdf install erlang 26.2.5
```

https://www.erlang.org/

## Elixir


こちらもasdfからインストールします。Elixirのバージョンだけでなく、Erlang/OTPのバージョンの指定が必要なので注意が必要です。

```bash
$ asdf plugin-add elixir https://github.com/asdf-vm/asdf-elixir.git
$ asdf install elixir 1.17.2-otp-26
```

インストールが完了したらシステム全体で使用するバージョンを指定します。

```
$ asdf global erlang 26.2.5
$ asdf global elixir 1.17.2-otp-26
```

## Node.js

TailwindなどのJavaScriptライブラリを管理するためにnpmを使用します。

今回はNode.jsのバージョン管理ツールnvmを使用してインストールを行います。

```bash
$ brew install nvm
$ nvm install v20.11.0
```

https://nodejs.jp/

https://github.com/nvm-sh/nvm

以上で環境構築は完了になります

# ElixirDesktopプロジェクトの作成

ElixirDesktopを使用したデスクトップ、iOS、Androidの各アプリケーションの作成方法について紹介します。

## Phoenixのセットアップ

ElixirDesktopのアプリケーションはPhoenixのプロジェクトをベースに開発を進めるため、
Phoenixのインストールが必要です。公式サイト[Phoenix Install](https://hexdocs.pm/phoenix/installation.html)の手順に沿って次のようにインストールしていきます。

```
$ mix local.hex
$ mix archive.install hex phx_new
```

== Phoenixプロジェクトの作成

Phoenixプロジェクトを作成するのですが、起動実験を行うだけなのでデータベースは使用しないオプションをつけて次のコマンドを実行します。

```
$ mix phx.new basic --no-ecto
```

コマンドを実行すると、関連するライブラリをインストールしますかと聞かれるので`y`を選択してください。

プロジェクトの作成が完了したら次のコマンドでPhoenixが問題なく起動できるか確認しましょう。

```
$ cd basic
$ mix phx.server
```

`http://localhost:4000`
 にアクセスし次のページが表示されれば成功です。

![02_03_open_phoenix.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64198/603561b1-e554-0d10-2eb2-41c785073db5.png)

## デスクトップアプリ化

Phoenixプロジェクトをデスクトップアプリ化を行います。

`mix.exs`にデスクトップアプリ化を行うライブラリを`deps`関数のライブラリリストの最後に追加します。

```elixir:mix.exs
  defp deps do
    [
      ...
      {:bandit, "~> 1.2"}, #末尾にコンマを追加
      {:desktop_setup, github: "thehaigo/desktop_setup", only: :dev} # 追加
    ]
  end
```

追加したら次のコマンドを実行していきます。

```bash
$ mix deps.get
$ mix desktop.install
```

完了したら次のコマンドでアプリを起動し、画像のように表示されれば成功です。

```
$ iex -S mix
```

![02_04_start_desktop_app.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64198/bf472a65-7555-977a-af60-d9d4ddd32caf.png)


## iOSアプリのセットアップ

デスクトップアプリをiOSで動作するように次のコマンドでセットアップを行い起動テストを行います。

```
$ mix desktop.setup.ios
```

完了したら `native/ios`ディレクトリが作成され、その中にXcodeのプロジェクトが作成されています。次のコマンドで移動し、初回起動に必要なファイル作成してXcodeを開きます。

```bash
$ cd native/ios
$ carthage update --platform iOS --use-xcframeworks
$ ./run_mix
$ open Basic.xcodeproj
```

Xcodeが起動するので、起動するシミュレーターを選択してスタートボタンを押してください。次の画面が表示されれば成功です。

![02_05_start_ios.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64198/320921e2-d53c-53d4-1b7c-341682178367.png)


## Androidアプリのセットアップ

デスクトップアプリをAndroidで動作するように次のコマンドでセットアップを行い起動テストを行います。

```
$ mix desktop.setup.android
```

完了したら `native/android`ディレクトリが作成され、その中にAndroidStudioのプロジェクトが作成されているので、AndroidStudioから次のように開きます。

![02_06_open_android_pj.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64198/3957bbf7-0925-e2b2-4dc8-781624ac99c1.png)

または、メニュー > open から開くこともできます

AndroidStudioが開いて、gradleの同期が完了したら、スタートボタンを押してください。

次の画面が表示されれば成功です。


![02_07_start_android.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64198/bb81cc85-6189-ab05-a96b-2d12e46c3006.png)


# まとめ

macOS上に環境構築し、Phoenixプロジェクトからデスクトップ、iOS、Androidのそれぞれのアプリをコマンド1つで作成し、起動することが確認できました。

このあとは APIサーバーに対して通信を行うなり、端末内のSQLiteや外部のPostgreSQLに接続して通常のPhoenixアプリのように開発が可能です

それぞれの実装方法は以下の記事でまとめているので、参考にしていたければと思います
- [クライアント、サーバー構成アプリ](https://qiita.com/the_haigo/items/4a63320fe504c5dface2#%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%88%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E6%A7%8B%E6%88%90%E3%82%A2%E3%83%97%E3%83%AA)
- [内部SQliteを使用したスタンドアローンアプリ](https://qiita.com/the_haigo/items/4a63320fe504c5dface2#%E3%82%B9%E3%82%BF%E3%83%B3%E3%83%89%E3%82%A2%E3%83%AD%E3%83%BC%E3%83%B3%E3%82%A2%E3%83%97%E3%83%AA%E7%B7%A8)
- [APIレス DB共有構成アプリ](https://qiita.com/the_haigo/items/4a63320fe504c5dface2#api%E3%83%AC%E3%82%B9-db%E5%85%B1%E6%9C%89%E6%A7%8B%E6%88%90%E3%82%A2%E3%83%97%E3%83%AA)

# 参考サイト

https://github.com/elixir-desktop/desktop
https://github.com/thehaigo/desktop_setup
https://github.com/elixir-desktop/desktop/blob/main/guides/getting_started.md
https://github.com/yonaskolb/XcodeGen
https://github.com/Carthage/Carthage
https://developer.android.com/studio
https://www.wxwidgets.org/
https://asdf-vm.com/guide/getting-started.html
https://github.com/asdf-vm/asdf-erlang
https://github.com/asdf-vm/asdf-elixir
https://www.erlang.org/
https://elixir-lang.org/
https://nodejs.jp/
https://github.com/nvm-sh/nvm
https://hexdocs.pm/phoenix/installation.html
https://qiita.com/the_haigo/items/4a63320fe504c5dface2