LoginSignup
14
1

はじめに

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

ElixirDekstopのiOSアプリを以下を参考にXCodeでプロジェクトを作るところから初めて
実際に起動するまで行います

フォルダ構成

別のネイティブアプリを作るライブラリにLiveViewNativeというものがあり、そのサンプルアプリのフォルダ構成が、 app_name/native/[ios or android pj]となっていたのでそちらを踏襲します

mkdir native

XcodeからiOSプロジェクトを作る

Xcodeを開き、新規プロジェクトを作成していきます

iOS Appを選択してNextをクリックします
スクリーンショット 2023-11-30 16.35.57.png

アプリ名を入力して nextをクリック

スクリーンショット 2023-11-30 16.36.35.png

作成先を先ほど作成した nativeの下に指定して Createをクリック

スクリーンショット 2023-11-30 16.36.58.png

作成したら
native/bookshelf/bookshelfとなっているので
native/ios/bookshelfとリネームしましょう

このときXcodeからRe Saveしますか?ときかれるのでキャンセルしてください

iOSサンプルアプリからファイルをコピー

サンプルアプリをXcodeで開き、以下のファイルをコピーしていきます

サンプルアプリ側の

  • ZIPFoundation -> zipファイルを操作するライブラリ
  • liberlang -> クロスコンパイルしたErlang実行バイナリ
  • native-lib.cpp -> liberlangを起動するスクリプト
  • native-lib.hpp -> 上記のヘッダーファイル
    を選択してドラッグアンドドロップでコピーします

スクリーンショット 2023-11-30 16.53.10.png

グループかリファレンスかとターゲットをきかれるので変更はせずにFinishをクリック

スクリーンショット 2023-11-30 16.53.17.png

次にBridge-Headerを作るかを訊かれるので Createをクリック

完了すると以下のようになります

スクリーンショット 2023-11-30 16.53.26.png

ヘッダーファイルの修正

Header.hファイルにnative-libのヘッダーファイルを読み込む設定を追加します

native/ios/bookshelf-Bridging-Header.h
#import "native-lib.hpp"

ライブラリ設定

VSCodeからCartfileのファイルを作成し、以下を追加します

native/ios/Cartfile
github "weichsel/ZIPFoundation" ~> 0.9

iosのフォルダに移動し以下を実行します

cd native/ios
carthage update --use-xcframeworks

インストールが完了したらXcodeでアプリの設定画面のGeneralタブを表示し、Frameworksの項目のliberlangZIPFoundationEmbedの項目をEmbed & Signにします

スクリーンショット 2023-09-27 13.49.00.png

WebViewアプリケーションと、ブリッジの作成

TodoApp.swiftのstructの内容をコピーします

native/ios/bookshelf/bookshelfApp.swift
import SwiftUI

@main
struct bookshelfApp: App {
    @Environment(\.scenePhase) var scenePhase
    
    var content = ContentView()
    var body: some Scene {
        WindowGroup {
            self.content
        }
        .onChange(of: scenePhase) { phase in
            switch phase {
            case .background:
                print(".background")
            case .active:
                print(".active")
                if let bridge = Bridge.instance {
                    bridge.reinit()
                }
            default: break
            }
        }
    }
}

アプリ起動時にconentを表示し、アプリがバックグラウンドになったらログを出力し、バックグラウンドからアクティブになったらPhoenixアプリケーションとのブリッジを再度作成します

もとからある ContentView.swiftを削除し、サンプルアプリから以下のファイルをドラッグアンドドロップでコピーします

  • ContentView.swift -> アプリの画面でセーフエリアとWebviewを表示
  • WebViewController.swift -> WebViewの初期化処理と画面更新時の処理
  • WebView.swift -> 表示するWebviewの設定
  • Bridge.swift -> Erlangの起動と接続処理

ビルドスクリプト作成

run_mixをVSCode経由でコピーしビルドスクリプトをPhoenix Projectに合わせて編集します

native/ios/run_mix
#!/bin/bash
set -e

# Setting up the PATH environment
[ -s /opt/homebrew/bin/brew ] && eval $(/opt/homebrew/bin/brew shellenv)
[ -s /usr/local/bin/brew ] && eval $(/usr/local/bin/brew shellenv)

# This loads nvm
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  

# This loads asdf
if [ -s "$HOMEBREW_PREFIX/opt/asdf/libexec/asdf.sh" ]; then 
  \. "$HOMEBREW_PREFIX/opt/asdf/libexec/asdf.sh" 
elif [ -s "$HOME/.asdf/asdf.sh" ]; then
  \. "$HOME/.asdf/asdf.sh"
fi

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
+ # Phoenix PJまでのパスに変更 
+ cd ../../

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

# tailwindのみの場合コメントアウト
# 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
+ # xcodeで作成したプロジェクト名に変更
+ if [ -f "$BASE/bookshelf/app.zip" ]; then
+  rm "$BASE/bookshelf/app.zip"
+ fi

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

ビルド実行

ErlangとElixirのバージョンを以下のコマンドで切り替えます

asdf global erlang 25.0.4
asdf global elixir 1.15.7-otp-25

iosのフォルダに移動してrun_mixを実行します

cd native/ios/
./run_mix

ビルドが正常に完了したら、bookshelfフォルダにapp.zipを追加します

スクリーンショット 2023-12-01 1.38.17.png

スクリーンショット 2023-12-01 1.38.57.png

ファイルを追加したらXcodeの実行ボタンをクリックすると以下のように表示されます

スクリーンショット 2023-12-01 1.41.01.png

最後に

Xcodeでプロジェクトを作るところから実際にElixirDesktopが動くところまでを実装しました
ファイルをXcode経由でコピーしたりといろいろ面倒なので、LiveViewNativeみたいに自動化されないかなーとは思っています

次はAndroidプロジェクトを作成していきます

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

14
1
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
14
1