DEV Community

Cover image for Mobile app development with LiveView Native and Elixir
Rushikesh Pandit
Rushikesh Pandit

Posted on • Updated on

Mobile app development with LiveView Native and Elixir

What is LiveView Native

LiveView Native is a new framework by Dockyard.

Do more with less, with LiveView Native

As their tag line suggests, it allows Elixir developers to create mobile applications using LiveView, enabling teams to seamlessly build both web and mobile applications with Elixir. Similar to how React Native works for JavaScript, LiveView Native enhances team efficiency by eliminating the need for multiple frameworks or programming languages.

According to DockYard CEO Brian Cardarella, "With Phoenix handling your web views, your mobile native views, and serving as your server-side framework, it creates a more unified and single-stack team."

LiveView Native empowers even small engineering teams to develop custom web and mobile applications, leveraging Elixir and LiveView’s speed, reliability, and concurrency benefits. It helps meet product deadlines faster by reducing obstacles and potential delays since one team can handle both web and native development.

The benefits extend beyond development, as a single team can manage both web and mobile applications, removing barriers related to multiple frameworks and languages, thus achieving more with fewer resources.

Additionally, LiveView Native doesn’t force developers to use a single UI across all platforms. Whether building for iOS or Android, it provides tools to create applications that look and function like true native products, using templates that utilize the native component UI for each platform.

Setup

Prerequisite: You have already installed elixir, phoenix framework along with Xcode and Android studio on you'r machine.

Since android version of LiveView Native is not stable yet, we will be setting up only iOS app in this blog.

With this enough information, let's start with building live view native with Phoenix application.

Let's start with creating phoenix app first with following command

mix phx.new native_demo
Enter fullscreen mode Exit fullscreen mode

Our actual live view integration starts from here.

Open project folder in any of your favourite code editor, I am using VS Code in this case.

Make sure that your project is using elixir version 1.15 and above.

Elixir vesion

Now start making changes in the code as shown below.

mix.exs

{:live_view_native, github: "liveview-native/live_view_native", branch: "main", override: true},
{:live_view_native_stylesheet, github: "liveview-native/live_view_native_stylesheet", branch: "main"},
{:live_view_native_swiftui, github: "liveview-native/liveview-client-swiftui", branch: "main"},
{:live_view_native_live_form, github: "liveview-native/liveview-native-live-form"},
{:live_view_native_jetpack, github: "liveview-native/liveview-client-jetpack", branch: "main"}
Enter fullscreen mode Exit fullscreen mode

And add following line to config.exs (I somehow missed this step, Thanks to @maratk )

config :live_view_native, plugins: [
  LiveViewNative.SwiftUI
]
Enter fullscreen mode Exit fullscreen mode

Post this, install dependencies manually using following command.

mix deps.get
Enter fullscreen mode Exit fullscreen mode

Live view native will some mix tasks to your project to help you out with setup of live view native.

Let's setup live view native in our app using following command in the terminal

mix lvn.setup
Enter fullscreen mode Exit fullscreen mode

This command will create some necessary files in our project.

You can learn more about lvn task from below command.

mix help lvn.swiftui.gen
Enter fullscreen mode Exit fullscreen mode

After that run the following command in the terminal

mix lvn.swiftui.gen
Enter fullscreen mode Exit fullscreen mode

This command will create new swiftui project under the native directory which got created automatically in the root directory of the project. Also it will create some core components for swiftui.

Incase you lost those changes from terminal, no need to worry. You can use following command to see it again.

mix lvn.gen --no-copy
Enter fullscreen mode Exit fullscreen mode

This command will show the list of changes that we are supposed to add manually into our application. Please make sure that your make all the changes that are mentioned under the header LVN - Required
This is the most crucial step in the live view native integration.

Now, head over to the components directory of the app and create new directory with the name layouts_swiftui and add 2 new files with the name app.swiftui.neex and root.swiftui.neex with following content.

root.swiftui.neex

<.csrf_token />
<Style url={~p"/assets/app.swiftui.styles"} />
<NavigationStack>
  <%= @inner_content %>
</NavigationStack>
Enter fullscreen mode Exit fullscreen mode

app.swiftui.neex

<%= @inner_content %>
Enter fullscreen mode Exit fullscreen mode

Then create a new directory with the name styles with the same level as that of components directory and add 2 new files with the name app.jetpack.ex and app.swiftui.ex with following content.

app.jetpack.ex

defmodule NativeDemoWeb.Styles.App.Jetpack do
  use LiveViewNative.Stylesheet, :jetpack

  ~SHEET"""
  """  
end

Enter fullscreen mode Exit fullscreen mode

app.swiftui.ex

defmodule NativeDemoWeb.Styles.App.SwiftUI do
  use LiveViewNative.Stylesheet, :swiftui

  ~SHEET"""
  """  
end

Enter fullscreen mode Exit fullscreen mode

Now, create a new directory with the name live with the same level as that of components directory and add 2 new files with the name home_live.ex and home_live.swiftui.ex with following content.

home_live.ex

defmodule NativeDemoWeb.HomeLive do
  use NativeDemoWeb, :live_view

  use LiveViewNative.LiveView,
    formats: [:swiftui],
    layouts: [
      swiftui: {NativeDemoWeb.Layouts.SwiftUI, :app}
    ]

  def render(assigns) do
    ~H"""
    <div>
      Hello from Web
    </div>
    """
  end
end
Enter fullscreen mode Exit fullscreen mode

home_live.swiftui.ex

defmodule NativeDemoWeb.HomeLive.SwiftUI do
  use NativeDemoNative, [:render_component, format: :swiftui]

  def render(assigns, _interface) do
    ~LVN"""
    <VStack id="hello-ios">
      <HStack>
        <Text>Hello iOS!</Text>
      </HStack>
    </VStack>
    """
  end
end
Enter fullscreen mode Exit fullscreen mode

Then, open the router.ex and add following code.

router.ex

After making those changes, folder structure of project's lib directory will look something like this.

lib directory structure

After this, head out to native/swiftui directory and open the file with the extension .xcodeproj and then when you try to run the app on simulator, xcode will show popup like shown below.

xcode popup

All that you have to do is click on Trust & Enable All.

Then try to re-run the application from xcode, you can see some error as shown below.

xcode error

Then you have to select any error, you will see following popup.

xcode popup

We need to click on Trust & Enable button. We have to perform this steps for all the errors.

Once you done with enabling all the macros, try to build and run the app.

If everything done properly, you should be able to see following screen on iOS simulator

Mobile app

and if you hit http://localhost:4000/home from your browser, should be able to see following.

Web app

If you are able to see this on your simulator and browser, congratulations. You have successfully integrated live view native into phoenix aplication.

You can find sample code on Github

In case if you face any issue, try deleting _build directory and compile code again using mix compile command.

If you have any suggestions/doubts or stuck somewhere in this process, feel free to reach to me via one of the following method.

LinkedIn : https://www.linkedin.com/in/rushikesh-pandit-646834100/
GitHub : https://github.com/rushikeshpandit
Portfolio : https://www.rushikeshpandit.in

In my next blog, I will be covering the about how to handle the states in web and mobile app when using live view native.

Counter demo

Stay tuned!!!

#myelixirstatus , #liveviewnative , #dockyard , #elixir , #phoenixframework

Top comments (12)

Collapse
 
maratk profile image
Marat

Opening prj file in the Xcode results in the following notice:
Image description

My Xcode version is 15.3. What should I do in this case?

Collapse
 
rushikeshpandit profile image
Rushikesh Pandit

Hi Marat, seems like existing code is written with Swift 3 which is not supported by your xcode version. Try to delete "native" folder and recreate it using command mix lvn.swiftui.gen

Let me if this helps you.

Collapse
 
maratk profile image
Marat

I removed native folder, ran mix lvn.swiftui.gen and opened .xcodeproj file.
The Xcode shows me same dialog window with text:

The target “QuizArena” contains source code developed with Swift 3.x. This version of Xcode does not support building or migrating Swift 3.x targets.

Use Xcode 10.1 to migrate the code to Swift 4.
Enter fullscreen mode Exit fullscreen mode

I don't have Xcode 10.1.

Does it mean this approach will not work for me?

Thread Thread
 
rushikeshpandit profile image
Rushikesh Pandit

Hi Marat. I belive this might be some environment related issue. Please email me on rushikesh.d.pandit@gmail.com with your good time to connect and we can take a look at it. I will be happy to help you.

Thread Thread
 
maratk profile image
Marat

Thank you!

Thread Thread
 
maratk profile image
Marat • Edited

Recap: to enable the successful build on the MacOS Sonoma Xcode 15 we had to add the following adjustments:

  1. Set Swift version 15 in the project Build Settings:

Image description

  1. Since I didn't have the iOS build type in the build platform list Image description

I had to download the iPhone simulator by opening Xcode > Settings > Platform, and downloading iOS 17 simulator, and also iPhone 15 simulator available under + button.

Image description

And selecting the needed simulator version in the list or Run Destinations:
Image description

  1. Adding iPhone destination in the NativeDemo target General settings: Image description

Image description

Image description

Image description

  1. Set product module name to avoid module name "" is not a valid identifier error in NativeDemo target Build settings Packaging section:

Image description

I'm a newbie in the iPhone development so probably product name could be simpler.

  1. Set the Base SDK architecture in the NativeDemo Build settings:

Image description

After doing this I was able to build the project successfully.

Happy coding!

Collapse
 
maratk profile image
Marat

Hi! Great article! Long-waited native development is coming!
However, I get error when I try to run mix lvn.swiftui.gen:

mix lvn.swiftui.gen
** (KeyError) key "swiftui" not found in: %{}
    :erlang.map_get("swiftui", %{})
    (live_view_native 0.3.0-rc.1) lib/live_view_native.ex:125: LiveViewNative.fetch_plugin!/1
    (live_view_native 0.3.0-rc.1) lib/mix/live_view_native/context.ex:60: Mix.LiveViewNative.Context.get_module_suffix/1
    (live_view_native 0.3.0-rc.1) lib/mix/live_view_native/context.ex:33: Mix.LiveViewNative.Context.build/2
    (live_view_native_swiftui 0.3.0-rc.1) lib/mix/tasks/lvn.swiftui.gen.ex:30: Mix.Tasks.Lvn.Swiftui.Gen.run/1
    (mix 1.16.0) lib/mix/task.ex:478: anonymous fn/3 in Mix.Task.run_task/5
    (mix 1.16.0) lib/mix/cli.ex:96: Mix.CLI.run_task/2
    /Users/marat/.asdf/installs/elixir/1.16.0/bin/mix:2: (file)
Enter fullscreen mode Exit fullscreen mode

Do you know what might be wrong?

Followed your instructions.
Versions

Erlang/OTP 26 [erts-14.1] [source] [64-bit] [smp:16:16] [ds:16:16:10] [async-threads:1] [jit:ns]

Elixir 1.16.0 (compiled with Erlang/OTP 24)
Enter fullscreen mode Exit fullscreen mode
Collapse
 
maratk profile image
Marat

Solved by adding

config :live_view_native, plugins: [
  LiveViewNative.SwiftUI
]
Enter fullscreen mode Exit fullscreen mode

to config.exs as described in the liveview-native/live_view_native readme.

Collapse
 
rushikeshpandit profile image
Rushikesh Pandit

Hi Marat, happy that you are able to solve it by yourself. In case you miss to add LiveView Native changes into your project, use mix lvn.gen --no-copy command to get the list of all the changes that we need to integrate manually.

Collapse
 
maratk profile image
Marat

After solving the packages error I have the following one:

Image description

Any idea how to solve this?

Collapse
 
maratk profile image
Marat

somehow I solved this and got the app running in the simulator. I must say that Xcode configuring is insane...

Collapse
 
rushikeshpandit profile image
Rushikesh Pandit

I am glad that you are able to run the app on simulator. Feel free to connect with me if you face any issues with xcode.