Configure a SwiftUI WebView for an 8th Wall WebAR Experience in 5 steps.

https://github.com/evanmcarlson/8thwall-ios-webview/tree/main

Step by step

  1. Create a new SwiftUI project in Xcode
  2. Create a new swift file, named WebView.swift
import Foundation
import SwiftUI
import WebKit

struct WebView: UIViewRepresentable {
    
    let url: URL
    
    func makeUIView(context: Context) -> WKWebView {
        let webView = WKWebView()
        let request = URLRequest(url: url)
        webView.load(request)
        return webView
    }
    
    func updateUIView(_ uiView: WKWebView, context: Context) {
        
    }
}
  1. Launch the WebView from ContentView.swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack {
            WebView(url: URL(string: "<https://8th.io/iframe>")!)
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
  1. Notice that we launch https://8th.io/iframe in the WebView. This tool will allow you to confirm all necessary permissions are propagated to the app correctly. If we try to request motion and camera now, both requests fail. Let's start with the camera.
  2. Configure the app to request motion sensors and camera
    1. Navigate to the Info tab of the target settings:

      Screen Shot 2023-06-21 at 10.39.38 PM.png

    2. Click the + button on one of the line items and from the dropdown of the new App Category select Privacy - Camera Usage Description. Provide a description of how the camera will be used as the value:

      Screen Shot 2023-06-21 at 10.39.48 PM.png

    3. If we test the WebView again, we will find the camera permissions are requested, but the camera pipeline gets stuck on in the has stream state. We must configure the WebView to permit inline media playback to draw the stream to the canvas:

      let webConfiguration = WKWebViewConfiguration()
      webConfiguration.allowsInlineMediaPlayback = true
      
      let webView = WKWebView(frame: .zero, configuration: webConfiguration)
      
    4. Now we can request camera permissions and draw the camera feed in our WebView! Let's move on to motion permissions. To request motion permissions, repeat step 5b for Privacy - Motion Usage Description. We also need to set the uiDelegate on our WKWebViewMotion:

      import Foundation
      import SwiftUI
      import WebKit
      
      struct WebView: UIViewRepresentable {
          
          let url: URL
          
          class Coordinator: NSObject, WKUIDelegate {
              var parent: WebView
      
              init(_ parent: WebView) {
                  self.parent = parent
              }
          }
          
          func makeCoordinator() -> Coordinator {
              Coordinator(self)
          }
          
          func makeUIView(context: Context) -> WKWebView {
              let webConfiguration = WKWebViewConfiguration()
              webConfiguration.allowsInlineMediaPlayback = true
      
              let webView = WKWebView(frame: .zero, configuration: webConfiguration)
              webView.uiDelegate = context.coordinator
              
              let request = URLRequest(url: url)
              webView.load(request)
              
              return webView
          }
          
          func updateUIView(_ uiView: WKWebView, context: Context) {
              
          }
      }
      

Resources

Displaying WebView in SwiftUI

Xcode 13 Missing Info.plist

Device Motion in WKWebView | Apple Developer Forums

WKUIDelegate | Apple Developer Documentation