Not ready to devote the time or resources to onboarding a new Elixir engineer? Book a free consult today to learn how we can help.
I’ve been working on web development for over a decade. I’ve done frontend, backend, and backend again. These days, I spend my time helping clients build their websites using Phoenix LiveView. While I’ve been curious about developing native mobile apps, I’ve always avoided it because it felt overwhelming. Learning not just one, but two completely new environments and languages seemed like too much work.
Last year, DockYard released the first public version of LiveView Native.
In Brian’s blog post, “Create Your First LiveView Native App Part 2: Forms”,
he encouraged readers to add :section
slots to simple_form/1
.
I saw this as the perfect opportunity to try writing my first pull request (PR) for the project.
Implementing slots in LiveView Native turned out to be straightforward. The syntax is the same as in regular LiveView, only the tags are different. Instead of HTML, they’re based on SwiftUI.
The biggest challenge came from understanding the SwiftUI documentation. For example, the official Section documentation lists initializers like:
init(content:header:)
init(content: () -> Content, footer: () -> Footer)
init(content: () -> Content, header: () -> Parent, footer: () -> Footer)
This was baffling to me.
Sometimes it says content:header:
, and other times it’s content: () -> Content, header: () -> Parent
.
Why does the function for header
return a Parent
while the function for footer
returns a Footer
?
Coming from a web development background, I expected these to behave more consistently,
as if they could all be the same type of content.
Clearly, I was missing something important.
For a web developer learning native development, these kinds of differences can be confusing.
With help from Brian and Carson Katri, one of the engineers developing LiveView Native, I finally got the SwiftUI implementation right. Next, it was time to test! Thanks to LVN Go, checking the code on an actual device was super easy. Writing automated tests, however, was more difficult. At the time, there wasn’t a proper test setup in place. After I brought this up, Brian added a few basic helpers so we could render the templates and compare their outputs.
And that was it, I had completed my first LiveView Native PR!
Conclusion
Writing LiveView Native code is pretty straightforward for developers who are already familiar with LiveView. But there are still some challenges to overcome:
- Understanding SwiftUI: The documentation and terminology assume a lot of knowledge about the platform. For web developers just starting with LiveView Native, this can be intimidating. LVN could benefit from more beginner-friendly guides that explain how to translate SwiftUI concepts into something familiar.
- Testing: Right now, the test setup is very basic. You can compare entire templates, but even small changes to properties or content can break the tests. Building a more robust testing framework will be an important step toward making LiveView Native production-ready.
Despite these hurdles, I’m excited about the potential of LiveView Native. This first PR was a great learning experience, and I can’t wait to see how the project evolves and how developers will use it in the future.