DEV Community

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

Posted on • Edited on

Mobile app development with LiveView Native and Elixir

What is LiveView Native

Introducing LiveView Native, the cutting-edge framework from Dockyard

Do more with less, with LiveView Native

On August 2nd, 2024, Dockyard released a new version of LiveView Native with the tag v0.3.0-rc.3. I have updated the code in this tutorial to support the latest release.

LiveView Native enables Elixir developers to build mobile applications with LiveView, streamlining web and mobile app development. Similar to React Native, it boosts team efficiency by removing the need for multiple frameworks and languages.

DockYard CEO Brian Cardarella says, "With Phoenix handling web views, mobile native views, and serving as the server-side framework, it creates a more unified team."

LiveView Native empowers small engineering teams to build custom web and mobile applications using Elixir and LiveView's speed, reliability, and concurrency benefits. It helps meet product deadlines faster by simplifying web and native development.

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

Additionally, LiveView Native allows developers to create native-looking applications for iOS and Android without forcing the use of a single UI across all platforms.

Setup

Prerequisite: You’ve installed Elixir, Phoenix framework, Xcode, and Android Studio. We’ll only set up the iOS app in this blog since the Android version of LiveView Native is unstable.

Let’s start building the live view native with the Phoenix application by creating the Phoenix app with the following command.

mix phx.new native_demo
Enter fullscreen mode Exit fullscreen mode

Our LiveView Native integration starts here.

Open the project folder in your preferred code editor, such as VS Code.

Make sure your project is using Elixir version 1.15 or higher.

Elixir vesion

Please begin implementing the changes in the code according to the instructions provided below.

mix.exs

{:live_view_native, "~> 0.3.0"},
{:live_view_native_stylesheet, "~> 0.3.0"},
{:live_view_native_swiftui, "~> 0.3.0"},
{:live_view_native_live_form, "~> 0.3.0"}
Enter fullscreen mode Exit fullscreen mode

Upon completing the aforementioned change, the next step is to install dependencies by entering the following command.

mix deps.get
Enter fullscreen mode Exit fullscreen mode

After installing all the dependencies, we need to execute one additional command.

mix lvn.setup
Enter fullscreen mode Exit fullscreen mode

This command will efficiently compile your code and promptly display the result as follows.

To set up your application with LiveView Native run:

> mix lvn.setup.config
> mix lvn.setup.gen
Enter fullscreen mode Exit fullscreen mode

So, if we execute the command mix lvn.setup.config we will be prompted as follows:

Write to config/config.exs
(y)es (n)o (d)iff
Enter fullscreen mode Exit fullscreen mode

Here, enter y. To check the difference, enter d for the output.

...|
64 64   |# Import environment specific config. This must remain at the bottom
65 65   |# of this file so it overrides the configuration defined above.
   66 + |config :live_view_native, plugins: [
   67 + |  LiveViewNative.SwiftUI
   68 + |]
   69 + |
   70 + |config :mime, :types, %{
   71 + |  "text/styles" => ["styles"],
   72 + |  "text/swiftui" => ["swiftui"]
   73 + |}
   74 + |
   75 + |config :phoenix_template, :format_encoders, [
   76 + |  swiftui: Phoenix.HTML.Engine
   77 + |]
   78 + |
   79 + |config :phoenix, :template_engines, [
   80 + |  neex: LiveViewNative.Engine
   81 + |]
   82 + |
   83 + |config :live_view_native_stylesheet,
   84 + |  content: [
   85 + |    swiftui: [
   86 + |      "lib/**/swiftui/*",
   87 + |      "lib/**/*swiftui*"
   88 + |    ]
   89 + |  ],
   90 + |  output: "priv/static/assets"
   91 + |
66 92   |import_config "#{config_env()}.exs"
67 93   |

Enter fullscreen mode Exit fullscreen mode

So, you will get these prompts for the following files.

  • config/config.exs
  • config/dev.exs
  • lib/lvtest_web/endpoint.ex
  • lib/lvtest_web/router.ex

After finalising the changes for the files mentioned above, it is crucial to execute the following command to produce the Xcode project.

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

Create a new directory named live at the same level as the components directory. Add 2 new files: home_live.ex and home_live.swiftui.ex with the specified 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 the following code.

router.ex

Upon implementing these modifications, the lib directory of the project will exhibit the following folder structure.

lib directory structure

After this, go to the native/swiftui directory and open the .xcodeproj file. When you run the app on the simulator, Xcode will display a popup as shown below.

xcode popup

Click Trust & Enable All, then rerun the application from Xcode to check for errors.

xcode error

After selecting an error, a popup will appear.

xcode popup

Click Trust & Enable for all errors. After enabling macros, build and run the app. The iOS simulator should display the expected screen if done correctly.

Mobile app

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

Web app

If you can see this on your simulator and browser, congratulations! You've successfully integrated live view native into the Phoenix application.

Sample code can be found on Github. If you encounter issues, try deleting the _build directory and recompile the code using the mix compile command.

Feel free to reach out to me if you have any questions or need assistance.
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 how to handle the states in web and mobile apps when using live view native.

Counter demo

Stay tuned!!!

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

Top comments (13)

Collapse
 
demo318 profile image
Devin Mork

This post just convinced me to build my startup on Phoenix instead of Rails. Thank you!

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

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

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.