I will attempt to publish this series once a week. I’ll miss some weeks—it happens—but overall we’ll keep communication open on progress with LiveView Native. I will also try to address any questions I’ve been asked that seem like a good idea to bring more attention to.
After a year and a half of keeping this project (mostly) a secret I publicly released what is the kickoff for the LiveView Native clients. We hope to deliver on a first-class native client experience for LiveView apps that wish to target vertically and horizontally across the modern device ecosystem. Within SwiftUI alone we should be able to target iOS, macOS, TvOS, and watchOS we are also working on clients for Jetpack Compose (Android), WinUI3 (Windows) and exploring one or two others.
During my presentation, I give a very vague roadmap of where I hope the projects will be by end of year. However, that roadmap will depend upon what I have to talk about today. Which is stepping back from the projects and putting them on the correct path.
Two Oversights From the Keynote
Before getting to what is happening I wanted to address two topics I forgot to during my keynote.
The first is about template naming. In my keynote I used the same
counter_live.html.heex template when I switch from the web demo to the native demo. If you were to look at the chat app example this starts to point in the direction of where I think we will be heading for template rendering.
First off, when a LiveView Native client connects to a LiveView server endpoint it will send along the platform information for the server to pattern match on. We will be releasing an Elixir package to make this drop-in but right now you can check out the ElixirConf Chat App’s handler for conditionally rendering the correct platform template. So the SwiftUI client would render
lobby_live.ios.heex (yes “heex” is HTML EEX, but let’s not split hairs at this point) instead of
The second is expectation setting. I should have been very clear that this is essentially a
v0.0.1-alpha release. So please play with it and ask questions, but if you want to build a production app be prepared for rapid and frequent API changes in the coming weeks and months. We are making zero guarantees on API stability at this point.
Building toward our first real release
In the dash to ElixirConf I gave the engineers a lot of freedom in exploring what was untrod ground. We were the first, to my knowledge, to attempt to do a server-side rendering to native client UI and being the first means we have to try things out and see what works and what doesn’t work. This is a process that requires patience, but I am confident in what has been built so far and that we have proven that LiveView Native is not only possible but also viable. So now we have to step back and do some clean up and extractions.
LiveView Native Core
I’m not sure if this will be the actual name, as I literally just came up with it right now, but the idea is that there is a significant portion of what currently comprises the SwiftUI client and the Jetpack Compose client that overlap: the Morphdom implementation and the LiveView client itself, what handles the server responses over the wire, how it handles events, etc. So we should do ourselves and future client creators a favor and extract this out.
Our immediate work will be to rewrite this common functionality into either a Rust or C lib that can be pulled in and wrapped. This allows us to quickly align all clients with any version bumps that break or require new functionality from upstream in LiveView itself. It also will incentivize new native clients to be written.
The cool thing is that we will probably just use LiveView’s own test suite to test our implementation. LiveView has Elixir implementations of what we need–they’re used when you test LiveView web apps. The unit tests are not comprehensive but most of the functional needs are represented in the integration tests. So we should be able to just pull in
phoenix_liveview as a test env dependency and do some changes at either compile-time or run-time to have our compiled implementations tested instead.
I don’t have an estimation yet of how much time this effort will take but it’s our priority at the moment. So you may see little movement on the clients for now as we focus on this first step. After that, it will be about updating the SwiftUI and the Jetpack Compose clients to integrate this new core functionality. Then we can focus on refactoring the client architectures.
One goal I want to keep honest about with these clients is that they need to be incredibly simple. We are aiming to cover the standard component sets for the target frameworks only in the clients. This allows us to lean more heavily on the source documentation. For example, if you want to find a SwiftUI component to use in LiveView Native you wouldn’t go through a list that we documented, you would go to the SwiftUI documentation and find the correct component name and automatically know how to convert that into a LiveView Native element. Our conventions need to be obvious, simple, and consistent.
There are many components in the Apple documentation that won’t be part of the SwiftUI client. They should be a family of components that you can import into your LiveViewNative project, registered with the LiveViewNative client. This registry system is already implemented. We’ll probably build out a site so new components can be added and found easily. We won’t host code, just an outbound link to the project’s home.
Over the next few weeks, I hope to share some positive progress reports. If there isn’t an update I’ll probably just not post and reference that in the next update.