How to integrate a WKWebView into an iOS SwiftUI project, configure the app to request camera and motion sensor permissions, and display the camera feed and motion data within the WebView.

Github repository

GitHub - evanmcarlson/8thwall-ios-webview: Example code on implementing a WebView iOS app which launches an 8th Wall WebAR experience.

  1. Create a new SwiftUI project.

  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:

      webview1.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:

      webview2.png

    3. If we test the WebView again, we will find the camera permissions are requested, but the camera pipeline gets stuck on "has stream". 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, we 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