27
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Phoenix 1.7とElixirDesktopでスマホアプリを作る セットアップ編

Last updated at Posted at 2022-11-15

はじめに

本記事はPhoenix1.7をベースとして、Phoenixプロジェクトをネイティブアプリ化するライブラリElixirDesktopを使用し、
スマホアプリを作成する手順を紹介する記事になります

この記事では、環境セットアップと、iOS,Androidのビルド環境を整えます

ElixirDesktopでスマホアプリ作成シリーズ

  1. Phoenix1.7とElixirDesktopでスマホアプリ開発 セットアップ編
  2. Phoenix1.7とElixirDesktopでスマホアプリ開発 認証機能編
  3. Phoenix1.7とElixirDesktopでスマホアプリ開発 CRUD編
  4. Phoenix1.7とElixirDesktopでスマホアプリ開発 GPSと地図アプリ編

※2023/3/1 Phoenix 1.7が正式版がリリースされたので修正しました

ElixirDesktopについて

ElixirDesktopはネイティブ環境(iOS, Android)でPhoenixサーバーを起動し、WebViewで画面を表示するするアーキテクチャをとっています

スクリーンショット 2022-11-15 15.04.51.png

Phoenix 1.7について

大きな変更として以下がありました

  • デフォルトCSSがTawilwindになった
  • phx.gen.auth のLiveView化
  • .form以外のデフォルトのHeexのコンポーネントの追加
  • パスのヘルパー機能にverified_routesが追加

verified_routesについては以下で記事にしています

実行環境

Elixir 1.14.1
Elrang 25.0.4
Phoenix 1.7.0
ElixirDesktop 1.4.2

setup

Erlang

こちらにそって ElixirDesktopにopensslをあわせたErlangをインストールします

一緒にxcodeでパッケージ管理ライブラリのcarthageもインストールします

brew install carthage openssl@1.1
export DED_LDFLAGS_CONFTEST="-bundle"
export KERL_CONFIGURE_OPTIONS="--without-javac --with-ssl=$(brew --prefix openssl@1.1)"
asdf install erlang 25.0.4

Phoenix

こちらに沿ってPhoenixを1.7.0-rcにします
1.7.0がリリースされたので以下で最新版がインストールされます

mix archive.install hex phx_new

アプリ構成

  • 認証付き
  • CRUD
  • Headerコンポーネント
  • BottomTabコンポーネント
  • DBはPostgresql

Project作成

開発はiOS, Android, Phoenixの3つのプロジェクトを1つのフォルダで分けて開発します

わかりやすくするために一度phx.newしたあとにphoenixにリネームします

mkdir spotties
cd spotties
mix phx.new spotties
mv spotties phoenix
cd phoenix
mix ecto.create

gitはプロジェクト毎にしたほうが管理が楽なのでphoenix以下でgit initします

git init
git add .
git commit -m 'init'
iex -S mix phx.server

localhost:4000にアクセスしてPhoenix 1.7.0が無事起動することが確認できました

スクリーンショット 2022-11-15 15.15.06.png

Desktop化

こちらに沿ってやっていきます

https://qiita.com/the_haigo/items/0fd907d24fdde1905aa2
depsにdesktopとスマホ用にwxを追加します

mix.exs
defmodule Spotties.MixProject do
  use Mix.Project
  defp deps do
    [
     ...,
     {:desktop, "~> 1.5"},
     {:wx, "~> 1.1", hex: :bridge, targets: [:android, :ios]}
    ]
  end
end
mix deps.get

もとからあるapplication.exを残して起動時のsupervisor周りを設定します
サンプルに習って設定ファイル等を保存するconfig_dirを掘る処理も追加します

lib/spotties.ex
defmodule Spotties do
  use Application

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

  @app Mix.Project.config()[:app]
  def start(:normal, []) do
    File.mkdir_p!(config_dir())
    # DB周り
    {:ok, sup} = Supervisor.start_link([Spotties.Repo], name: __MODULE__, strategy: :one_for_one)
    # PubSubとEndpoint,session周り
    {:ok, _} = Supervisor.start_child(sup, SpottiesWeb.Sup)
    # Desktop周り
    port = :ranch.get_port(SpottiesWeb.Endpoint.HTTP)
    {:ok, _} =
      Supervisor.start_child(sup, {
        Desktop.Window,
        [
          app: @app,
          id: SpottiesWindow,
          title: "Spotties",
          size: {400, 800},
          url: "http://localhost:#{port}"
        ]
      })
  end
end

※ 2023/3/2追記
urlのport部分を4000にするとElixirDesktopのPhoenixではなく、ローカルのPhoenixにアクセスしてくれるのでエミュレータ等での開発はこちらが良いかと思います

lib/spotties_web/sup.ex
defmodule SpottiesWeb.Sup do
  use Supervisor

  def start_link([]) do
    Supervisor.start_link(__MODULE__, [], name: __MODULE__)
  end

  def init([]) do
    children = [
      {Phoenix.PubSub, name: Spotties.PubSub},
      SpottiesWeb.Endpoint
    ]

    :session = :ets.new(:session, [:named_table, :public, read_concurrency: true])
    Supervisor.init(children, strategy: :one_for_one, max_restarts: 1000)
  end
end

EndpointをPhoenixからDesktopに変えて Endpoint.urlがなくなったのでEndpointはそのままにして、session管理をcookieからetsに変更します

lib/spotties_web/endpoint.ex
defmodule SpottiesWeb.Endpoint do
  use Phoenix.Endpoint, otp_app: :spotties

  @session_options [
    store: :ets,
    key: "_spotties_key",
    table: :session
  ]
  ...
end

作成したら mix.exsで起動させるモジュールを変更します

mix.ex
defmodule Spotties.MixProject do
  use Mix.Project

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

Desktopで起動

開発を行うdev環境として、wxwidgetsの設定をします
server: trueを追加します

config/dev.exs
config :spotties, SpottiesWeb.Endpoint,
  # Binding to loopback ipv4 address prevents access from other machines.
  # Change to `ip: {0, 0, 0, 0}` to allow access from other machines.
  http: [ip: {127, 0, 0, 1}, port: 4000],
  ...,
  server: true # 追加

以下で起動します

iex -S mix

ホットリロードはできますが、リロードボタンがないのでホットリロードされないエラーになった場合は再起動が必要です

スクリーンショット 2022-11-15 23.32.36.png

iOS,Android共通設定

runtime.exがあると起動に失敗するので runtime_disable.exにリネームします

スマホは prod環境で動かすので config/prod.exにDBとEndpointの設定を追加します

config/prod.exs
config :spotties, Spotties.Repo,
  username: "postgres",
  password: "postgres",
  database: "spotties_dev",
  stacktrace: true,
  show_sensitive_data_on_connection_error: true,
  pool_size: 10

if Mix.target() == :ios do
  config :spotties, Spotties.Repo, hostname: "127.0.0.1"
end

if Mix.target() == :android do
  config :spotties, Spotties.Repo, hostname: "10.0.2.2"
end

config :spotties, SpottiesWeb.Endpoint,
  http: [ip: {127, 0, 0, 1}, port: 0],
  live_view: [signing_salt: "nt9pr/6W"],
  secret_key_base: "cVZaz98CBZNGr4dk7XhVqYpW49We6OKdzORLS20peE0ZK8Qv3ex6uOLujx/mXS80",
  server: true,
  cache_static_manifest: "priv/static/cache_manifest.json"

iOS Simulatorで動かす

プロジェクトフォルダにios-exampleをcloneします
cloneしたらxcodeのライブラリもインストールします

git clone https://github.com/elixir-desktop/ios-example-app.git ios
cd ios
carthage update --use-xcframeworks

Librariesの liberlangがembedされないので、 Embed & Signに変更します
スクリーンショット 2022-11-15 23.53.35.png

run_mixがビルドスクリプトなのでphoenixプロジェクトに合わせて変更します

#!/bin/bash
...
BASE=`pwd`
export MIX_ENV=prod
export MIX_TARGET=ios

mix local.hex --force --if-missing
mix local.rebar --force --if-missing

- if [ ! -d "elixir-app" ]; then
-  git clone https://github.com/elixir-desktop/desktop-example-app.git elixir-app
- fi

- # using the right runtime versions
- if [ ! -f "elixir/.tool-versions" ]; then
-  cp .tool-versions elixir-app/
- fi

- cd elixir-app
+ cd ../phoenix

if [ ! -d "deps/desktop" ]; then
  mix deps.get
fi

# 追加したライブラリが無いのでコメントアウト
# if [ ! -d "assets/node_modules" ]; then
#   cd assets && npm i && cd ..
# fi

if [ -f "$BASE/todoapp/app.zip" ]; then
  rm "$BASE/todoapp/app.zip"
fi

mix assets.deploy && \
  mix release --overwrite && \
-  cd _build/ios_prod/rel/todo_app && \
+  cd _build/ios_prod/rel/spotties && \
  zip -9r "$BASE/todoapp/app.zip" lib/ releases/ --exclude "*.so"

xcodeの実行ボタンを押してビルドします
ビルドエラーがでて、原因がわからない場合は以下を実行してログをみて見ましょう

./run_mix 

スクリーンショット 2022-11-16 0.09.30.png

Android Emunlatorで動かす

git clone https://github.com/elixir-desktop/android-example-app.git android

AndroidStudioで cloneしたandroidを開きます、gradle syncがちょっとかかるので待ちましょう
ビルドスクリプトを書き換えます

#!/bin/bash
set -e

BASE=`pwd`
APP_FILE="$BASE/src/main/assets/app.zip"
export MIX_ENV=prod
export MIX_TARGET=android

- if [ ! -d "elixir-app" ]; then
-  git clone https://github.com/elixir-desktop/desktop-example-app.git elixir-app
- fi

# using the right runtime versions
- if [ ! -f "elixir-app/.tool-versions" ]; then
-  cp .tool-versions elixir-app/
- fi

- cd elixir-app
+ cd ../../phoenix

if [ ! -d "deps/desktop" ]; then
  mix local.hex --force
  mix local.rebar
  mix deps.get
fi

# ライブラリを追加していないのでコメントアウト
# if [ ! -d "assets/node_modules" ]; then
#  cd assets && npm i && cd ..
# fi

if [ -f "$APP_FILE" ]; then
  rm "$APP_FILE"
fi

mix assets.deploy && \
  mix release --overwrite && \
-  cd "_build/${MIX_TARGET}_${MIX_ENV}/rel/todo_app" && \
+  cd "_build/${MIX_TARGET}_${MIX_ENV}/rel/spotties" && \
  zip -9r "$APP_FILE" lib/ releases/ --exclude "*.so"

ビルド時に以下のエラーが出たらJavaのバージョンが古いと怒られているので、
メニューバーの Android Studio > preferences > Build,Execution > Build Tools > Gradle を開き Gradle JDKを11以上にしてください

Android Gradle plugin requires Java 11 to run. You are currently using Java 1.8

それでもビルドに失敗した場合は run_mixがあるフォルダに移動してビルドを実行してログを見ましょう

cd android/app
./run_mix

スクリーンショット 2022-11-16 0.21.03.png

最後に

無事 WxWidget, iOS, Androidそれぞれでアプリとして起動できました

開発を進める場合はデベロッパーコンソールがあるので、PhoenixをWebアプリとして起動したほうが楽かもしれなません
Phoenixもmix_targetによって起動できるようにする構築手順は以下なります

本記事は以上になります、ありがとうございました
次は実際にアプリを作っていこうと思います

参考ページ

https://qiita.com/the_haigo/items/27bf18acd28971af31e9
https://qiita.com/the_haigo/items/bc848d80ff8fdf6ffa79
https://github.com/phoenixframework/phoenix/tree/master/installer
https://github.com/elixir-desktop/desktop
https://github.com/elixir-desktop/ios-example-app
https://github.com/elixir-desktop/android-example-app

27
9
2

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
27
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?