DocumentationAPI Reference
API ChangelogOpenAPI SpecStatus

Quickstart: iOS WKWebView

❗️

WebView is not recommended

We recommend using our native mobile SDKs (Android, iOS) instead of WebView. WebView integrations experience lower conversion due to reduced performance. Support for WebView integration is only available for Enterprise customers.

For more information, see Native mobile integration vs. WebView.

Below are some code snippets to get you integrating with the WebView API as soon as possible.

415

Example WebView on iOS in Sandbox mode

Demo App

If you just want to kick the tires on the WebView, we have an open source example app available at persona-id/persona-ios-webview that you can clone and open in Xcode.

Example Code

To use WKWebView to launch the inquiry flow from a UIViewController with the options laid out on WebView Flow.

// Create the web view and show it
private lazy var webView: WKWebView = {
  let config = WKWebViewConfiguration()
  // allowsInlineMediaPlayback is required, as it defaults to false on some devices like iPads.
  // If unset, will cause the camera capture flow to be fullscreen instead of inline.
  config.allowsInlineMediaPlayback = true

  let webView = WKWebView(frame: .zero, configuration: config)
  return webView
}()
webView.navigationDelegate = self
webView.allowsBackForwardNavigationGestures = false
webView.scrollView.bounces = false
// Add the web view and set up its contstraints
view.addSubview(webView)
webView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
    webView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
    webView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
    webView.topAnchor.constraint(equalTo: view.topAnchor),
    webView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
])

// Add the Persona configuration options as query items.
// See the Persona docs (<http://documentation.withpersona.com)> for full documentation.
var components = URLComponents(string: "<https://withpersona.com/verify")>
components?.queryItems = [
    URLQueryItem(name: "is-webview", value: "true"),
    URLQueryItem(name: "environment-id", value: "<your template ID starting with env_>"),
    URLQueryItem(name: "template-id", value: "<your template ID starting with itmpl_>"),
    URLQueryItem(name: "reference-id", value: "myReference"),
    URLQueryItem(name: "redirect-uri", value: "<https://myRedirectUri.com>"),
    // optional - specify theme for new inquiry
    // URLQueryItem(name: "theme-id", value: "the_Z7S2Ltor9fp2oEGXMLXBPsHa"),
]

// Create and load the Persona URL request
guard let urlString = components?.string, let url = URL(string: urlString) else { return }
let request = URLRequest(url: url)
webView.load(request)

When the WebView Flow is completed the WKWebView is redirected to the redirect-uri provided above. On a successful completion, the inquiry-id and reference-id (if set) will be appended as query string parameters More information in on these attributes can be found in Redirecting On Complete or Cancel.

extension MyViewController: WKNavigationDelegate {

    /// Handle navigation actions from the web view.
    func webView(_ webView: WKWebView, 
        decidePolicyFor navigationAction: WKNavigationAction, 
        decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        
        // Check if we are being redirected to our `redirectUri`. This happens once verification is completed.
        guard let redirectUri = navigationAction.request.url?.absoluteString, redirectUri.starts(with: "<https://myRedirectUri.com")> else {
            // We're not being redirected, so load the URL.
            decisionHandler(.allow)
            return
        }

        // At this point we're done, so we don't need to load the URL.
        decisionHandler(.cancel)

        // Get the inquiryId from the query string parameters.
        guard let queryParams = parseQueryParameters(url: navigationAction.request.url),
            let inquiryId = queryParams["inquiry-id"] else {

            // If we do not have an inquiry ID we know we have failed verification.
            // You will likely want to transition the view here to show this.
            return
        }

        // If we have an inquiry ID we know we have passed verification.
        // You will likely want to transition the view here to show this.
    }
}

Common Issues

❗️

Webkit Inline Media Playback

Please ensure allowsInlineMediaPlayback is enabled when creating a webview on a webkit browser (mobile Safari). This defaults to false and the camera preview will incorrectly open as a fullscreen live broadcast.

❗️

Camera Configuration

The WebView Flow requires access to the device camera. Please include the NSCameraUsageDescription key your app's Info.plist file as described in the Apple Developer documentation.

❗️

Allow External Network Requests

Persona makes external network calls within the Inquiry Flow that need to be allowlisted for the flow to properly function. Certain frameworks such as Cordova require such requests to be allow listed. Please include *.withpersona.com/* in such an allow list if needed.