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
Make sure you've selected the SwiftUI
user interface
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!
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
- The Ultimate Guide to WKWebView
- WebKit in SwiftUI with SegmentedControl, WebView, State, UIViewRepresentable
If you have any tips or feedback please get in touch via Twitter.
Top comments (1)
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