22
5

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.

ElixirAdvent Calendar 2022

Day 20

あらゆるネイティブアプリを作るライブラリ?! LiveViewNativeの紹介

Last updated at Posted at 2022-12-21

はじめに

この記事は「Elixir Advent Calendar 2022」vol1 20日目の記事です.

ElixirConf 2022 USで発表されたLiveView Nativeの解説します

LiveViewNativeとは

Phoenix LiveViewを共通プロトコルとしたマルチプラットフォーム

スクリーンショット 2022-12-21 20.39.48.png

LiveView Nativeは、Phoenixを使用してネイティブアプリケーションとWebアプリケーションをシームレスに構築できるようにするものです。
複数のチームを管理したり、複数のフレームワークを使いこなす必要はありません。
同じ開発者が両方を管理することで、納期を短縮し、イノベーションに集中するためのリソースを確保できます。

LiveView Nativeの特徴

LiveView Nativeを使用することで、単一のチームがWebおよびネイティブアプリケーションのフロントエンド開発を実行し、Phoenixのサーバーサイドレンダリングの利点を活用することが可能になりました。ElixirがWebにもたらす多くの利点を、今度はネイティブ環境で実感してください。

  • 複雑なクライアントサイドのアプリケーションを、重いJavaScriptフレームワークで構築するよりも高速かつ軽量に構築できます。
  • あらゆるプラットフォームでより良いユーザー体験を提供(「不気味の谷」現象はもう起きない)
  • Webとネイティブにまたがる単一のコードベースを管理する単一チームによる生産性とリソースの最適化

ElixirConf USざっくり

  • Phoenix LiveViewをプロトコルとしたネイティブプラットフォーム実装
  • バックエンドにPhoenixをそのまま使う
  • フロント部分を各ネイティブ環境用のDSLで記述し、クライアント側で解析して画面を組み立てる
  • ElixirConf USでLiveViewNativeで実装されたiOS製のチャットアプリをリリースして実際にイベントの交流ツールとして使用した

-> すでにプロダクションで使われている

LiveViewNativeとElixirDesktopの違い

LiveViewNative ElixirDesktop
ネイティブUIで表示 WebViewで表示
外部Phoenixサーバー 内部Phoenixサーバー
ネイティブ機能と連携容易 WebViewを通してネイティブ機能を使用
個々のネイティブUIの知識が必要 Webアプリの知識で実装可能

LiveViewNative アーキテクチャざっくり

  1. Swift側から LiveViewCoordinatorで接続先を指定
  2. Phoenix側で index.ios.heexというSwiftUIのコンポーネントのDSLで書いたLiveViewページを表示
  3. liveview-client-swifuiでそのデータを元に画面をビルドする

スクリーンショット 2022-12-21 21.14.14.png

Swift側でやること

  • PhoenixLiveViewNativeを読み込む
  • LiveViewCoordinatorを作成
  • ナビゲーション等の設定
  • PhoenixサーバーのURLをセット
  • ContentViewで LiveViewを表示

実際のコード

import SwiftUI
import PhoenixLiveViewNative

struct ContentView: View {
    @State var coordinator: LiveViewCoordinator<MyRegistry> = {
        var config = LiveViewConfiguration()
        config.navigationMode = .enabled
        return LiveViewCoordinator(
            URL(string: "http://localhost:4000/cats")!,
            config: config
        )
    }()
    var body: some View {
        LiveView(coordinator: coordinator)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Phoenix側でやること

  • URLに対応した.ios.heexをつくる
  • DSLでviewを記述
  • ページ単位ではなくアプリ全体でstateを管理するGenServerの作成(なくても作れる)
cat_live.ex
defmodule LvnTutorialWeb.CatLive do
  use LvnTutorialWeb, :live_view
  require EEx
  alias LvnTutorial.FavoritesStore

  EEx.function_from_file(
    :def,
    :render,
    "lib/lvn_tutorial_web/live/cat_live.ios.heex",
    [:assigns],
    engine: Phoenix.LiveView.HTMLEngine
  )

  def mount(%{"name" => name}, _sesion, socket) do
    {:ok,
     assign(socket,
       name: name,
       favorite: Enum.member?(FavoritesStore.get_favorites(), name),
       score: FavoritesStore.get_score(name)
     )}
  end
  ...
end

EEx.function_from_fileでの設定はライブラリを開発中なのでもう少し簡単になると思います

cats_list_live.ios.heex
<list navigation-title="Cats!">
  <%= for {name, favorite} <- @cats_and_favorites do %>
    <navigationlink 
      id={name} 
      data-phx-link="redirect" 
      data-phx-link-state="push" 
      data-phx-href={Routes.live_path(@socket, LvnTutorialWeb.CatLive, name)}
    >      
        <hstack id={name}>
        <asyncimage src={"/images/phoenix.png"} frame='{"width": 100, "height": 100}' />
        <text><%= name %></text>
        <spacer />
        <button phx-click="toggle-favorite" phx-value-name={name}>
          <image system-name={if favorite, do: "star.fill", else: "star"} symbol-color={if favorite, do: "#f3c51a", else: "#000000"} />
        </button>
      </hstack>
    </navigationlink>
  <% end %>
</list>

Swift側でできること

  • coordinator.pushEventでPhoenix側のイベントを発火
    -> センサデータや写真などをPhoenix側に送信するのが容易
  • カスタムコンポーネントを作成してPhoenix側で使用
  • iOSだけでなくmacOS, watchOS, tvOSのアプリも作れる

チュートリアルサイト

実際に試してみたい方はこちら!

スクリーンショット 2022-12-21 21.28.22.png

ロードマップ

image.png

  • SwiftUIの全コンポーネントをカバー
  • Jetpack対応
  • WinUI3対応

展望

image.png

iOS,Android, Windowsだけでなく、C# Channels clientを通してUnityを操作できるようにするという恐ろしい計画があるそうです

最後に

いかがでしたでしょうか
すでにiOSアプリのフロントをLiveViewのDSLで記述し、バックエンド及びステート管理をLiveViewで実装できる激アツプロダクトだと思います

今年はまだα版な感じでまだこなれてないのと、あまり時間がないので触れてないですが
来年はこれを使ってアプリを実際に作りたいと思います

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

参考サイト

https://speakerdeck.com/thehaigo/elixirconfxi-garideliveviewnativeyatutemita
https://liveviewnative.github.io/liveview-client-swiftui/tutorials/yourfirstapp/
https://github.com/liveviewnative/liveview-client-swiftui
https://www.youtube.com/watch?v=dnDGh_Jmw-s

22
5
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
22
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?