DEV Community

Cover image for Build a Hybrid SwiftUI app for iOS with Phoenix LiveView
Richard Taylor
Richard Taylor

Posted on • Originally published at richardtaylor.dev

Build a Hybrid SwiftUI app for iOS with Phoenix LiveView

I've succesfully published hybrid mobile apps with Turbolinks iOS in the past but Phoenix LiveViews are better suited due to the websocket event handling there is little (or no) HTTP navigation happening.

To demonstrate this we're going to build an iOS app for Flappy Phoenix a LiveView game I created previously.

Create a new iOS project using Single View App in Xcode

image

Make sure you've selected the SwiftUI user interface

image

Using SwiftUI we need very little code to get the WebView onto the screen. Update the generated ContentView with

// ContentView.swift

import SwiftUI
import WebKit

struct ContentView: View {
  var body: some View {
    WebView().edgesIgnoringSafeArea(.all)
  }
}

struct WebView: UIViewRepresentable {
  func makeUIView(context: Context) -> WKWebView {
    let webView = WKWebView()
    webView.scrollView.isScrollEnabled = false
    return webView
  }

  func updateUIView(_ webView: WKWebView, context: Context) {
    let liveView = "https://plappy-phoenix.herokuapp.com/game"
    if let url = URL(string: liveView) {
       let request = URLRequest(url: url)
       webView.load(request)
    }
  }
}

#if DEBUG
struct ContentView_Previews : PreviewProvider {
  static var previews: some View {
    ContentView()
  }
}
#endif

This results in a playable iOS app that wraps the LiveView!

Flappy Phoenix

It is now possible to extend the interface with SwiftUI components to make it feel more native, while keeping the main body of the app served via the LiveView.

struct ContentView: View {
  var body: some View{
    NavigationView {
      VStack{
        WebView()
      }
      .navigationBarTitle(Text("Flappy Phoenix"))
      .edgesIgnoringSafeArea(.all)
    }
  }
}

This is a simplified example, but hopefully it sparks your imagination of what is possible with LiveView hybrid apps.

In this case I haven't had to make any modifications to the web application but often you might want to make some changes on the server-side eg. hiding the web navigation if you're replacing it with native navigation.

To achieve this we can set a custom user agent in the WebView and then respond to that in the web application:

webView.customUserAgent = "FlappyPhoenix iOS"

If you have any tips or feedback please get in touch via Twitter.

Resources

If you have any tips or feedback please get in touch via Twitter.

Top comments (1)

Collapse
 
theomarie profile image
Theo

hello I'm a beginner in development Swift I can't implement a function
webView:didFailProvisionalNavigation:withError:
to check if the page loads correctly or return an error page that informs the user that he has no connections.

can you do a job explaining how to do it??

thank you for your work