LoginSignup
16
3

ElixirDektopのアプリを mix phx.newから自分で作る

Last updated at Posted at 2023-11-29

はじめに

この記事は Elixirアドベントカレンダーのシリーズ4の4日目の記事です

ElixirDekstopのアプリを mix phx.newで0から作って、デスクトップアプリとしてPhoenixのデフォルトページを表示するところまで行います

環境

macOS 14 Sonoma
Elixir 1.15.7-opt-26
Erlang 26.2

iOS、Androidのサンプルに合わせて Erlangのバージョンは 25.0.4がいいのですが
Desktopアプリを起動するときに使うwxwidgetのパスをビルド時に解消できずデスクトップアプリが起動できないため、その問題を解消している Erlang 26.2を使用します

Erlang,Elixirをインストール

Erlangのインストール必要なライブラリを以下を参考にインストールします
https://github.com/asdf-vm/asdf-erlang

brew install git openssl npm wxwidgets openjdk autoconf libxslt fop

必要なライブラリのインストールが完了したらErlangとElixirをインストールします

asdf install erlang 26.2
asdf install elixir 1.15.7-opt-26

インストールしたらグローバルで使用するバージョンとして指定します

asdf global erlang 26.2
asdf global elixir 1.15.7-otp-26

プロジェクト内だけ指定したい場合は phx.newしたあとにフォルダ内でasdf currentとすることで .tool-versionsが作成されます

Phoenix Frameworkのセットアップ

以下のコマンドでパッケーマネージャのセットアップを行います

mix local.hex

以下のコマンドでジェネレーターのphx_newをセットアップを行います

mix archive.install hex phx_new

Phoenix Projectの作成

セットアップが完了したのでPhoenix Projectを作成していきます
今回はスマホアプリでよくあるようなAPIサーバーを立ててデータのやり取りを粉う形式ではなく、
アプリ単体で完結できるスタンドアローンなアプリケーションを作成してきます

またDBはデフォルトのpostgresqlではなく Sqlite3を使用します

以下のようなアプリを作成していきます

  • 本棚アプリ bookshelf
  • 本棚のCRUD
  • 書籍データをGoogle Books APIから取得して本棚に追加

データベースを指定するときは --databaseオプションをつけます

mix phx.new bookshelf --database sqlite3

プロジェクトの作成が完了したら、ログに従ってプロジェクトフォルダに移動してDBを作成しましょう

cd bookshelf
mix ecto.create

次に以下のコマンドでウェブサーバーを起動させます

mix phx.server

localhost:4000にアクセスすると問題なく起動しているのが確認できました

スクリーンショット 2023-11-28 23.20.10.png

ライブラリの追加

次はデスクトップアプリとして動くようにしていきます
以下の3つのライブラリを追加します

mix.exs
  defp deps do
    [
      ...
      {:exqlite, github: "elixir-desktop/exqlite", override: true},
      {:desktop, "~> 1.5"},
      {:wx, "~> 1.1", hex: :bridge, targets: [:android, :ios]}
    ]
  end

追加したらmix deps.getを実行しましょう

config修正

configファイルをElixirDesktopに合わせて変更します
Endpointの設定を以下のように変更します

config/config.exs
...
config :bookshelf, BookshelfWeb.Endpoint,
-  url: [host: "localhost"],
+  http: [ip: {127, 0, 0, 1}, port: 10_000 + :rand.uniform(45_000)],
  adapter: Phoenix.Endpoint.Cowboy2Adapter,
  render_errors: [
    formats: [html: BookshelfWeb.ErrorHTML, json: BookshelfWeb.ErrorJSON],
    layout: false
  ],
  pubsub_server: Bookshelf.PubSub,
- live_view: [signing_salt: "3YOiiVQi"]
+ live_view: [signing_salt: "3YOiiVQi"],
+ secret_key_base: :crypto.strong_rand_bytes(32),
+ server: true
...

portの設定はiOSのバックグラウンドモードからの復帰時に必要です
server: trueとすることで、スマホ内で起動したPhoenixアプリケーションをWebViewから閲覧ができます

config/runtime.exsがあるとエラーになるのでruntime_disable.exsにリネームします

Endpoint設定

EndpointのモジュールをPhoenixからDesktopに変更します
ブラウザではないのでセッション管理をcookieから EralangビルドインインメモリDBのetsに変更します

lib/bookshelf_web/endpoint.ex
defmodule BookshelfWeb.Endpoint do
-  use Phoenix.Endpoint, otp_app: :bookshelf
+  use Desktop.Endpoint, otp_app: :bookshelf

  @session_options [
-    store: :cookie,
+    store: :ets,
     key: "_bookshelf_key",
+    table: :session
-    signing_salt: "YBmbGVCM",
-    same_site: "Lax"    
  ]
  ... 
end

アプリケーション起動時の設定

アプリケーション起動時に実行される、プロセス監視を行うsuperviserの設定を行います

lib/bookshelf.ex
defmodule Bookshelf do
  use Application

  def config_dir() do
    Path.join([Desktop.OS.home(), ".config", "bookshelf"])
  end

  @app Mix.Project.config()[:app]
  def start(:normal, []) do
    # configフォルダを掘る
    File.mkdir_p!(config_dir())

    # Databaseのパスをセット
    Application.put_env(:bookshelf, Bookshelf.Repo,
      database: Path.join(config_dir(), "/database.sq3")
    )

    # session用のETSを起動
    :session = :ets.new(:session, [:named_table, :public, read_concurrency: true])

    children = [
      Bookshelf.Repo,
      {Phoenix.PubSub, name: Bookshelf.PubSub},
      BookshelfWeb.Endpoint
    ]

    opts = [strategy: :one_for_one, name: Bookshelf.Supervisor]
    # メインのsuperviser起動
    {:ok, sup} = Supervisor.start_link(children, opts)


    # phoenixサーバーが起動中のポート番号を取得
    port = :ranch.get_port(BookshelfWeb.Endpoint.HTTP)
    
    # メインのsuperviserの配下にElixirDesktopのsuperviserを追加
    {:ok, _} =
      Supervisor.start_child(sup, {
        Desktop.Window,
        [
          app: @app,
          id: BookshelfWindow,
          title: "bookshelf",
          size: {400, 800},
          url: "http://localhost:#{port}"
        ]
      })
  end

  def config_change(changed, _new, removed) do
    BookshelfWeb.Endpoint.config_change(changed, removed)
    :ok
  end
end

アプリケーション設定ファイルを差し替えます

mix.exs
  def application do
    [
-      mod: {Bookshelf.Application, []},
+      mod: {Bookshelf, []},
      extra_applications: [:logger, :runtime_tools]
    ]
  end

動作確認

デスクトップアプリとして起動する準備が整ったので、以下のコマンドを実行します

iex -S mix 

無事デスクトップアプリとして起動できました

スクリーンショット 2023-11-29 13.11.50.png

最後に

今回はmix phx.newで通常のPhoenix Projectを作成してデスクトップアプリとして起動するところまでを行いました、
通常のwebアプリケーションに少し手を加えるだけでデスクトップアプリ化できることがわかったかと思われます

次はiOSプロジェクトを0から作っていきます

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

16
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
3