iOS App Webview

Integrating the DataGuard CPM Manage Widget into an iOS app can be efficiently achieved using a WKWebView. This approach allows you to leverage the full functionality of the Manage Widget with minimal setup.

Before you begin, ensure that you have a Template and a process in place to generate Citizen Tokens using our API, which are necessary for authenticating users within the widget. See the Citizen Tokens page for more information.

Step 1: Creating the Web Content

First, you need to create the HTML content that the WKWebView will render. Add a file named index.html to the root of your Xcode project with the content below.

Note: make sure the script URL and the Template id is correct for your environment and tenant. See the Manage Widget page for more information.

<head>
    <meta name="viewport" content="width=device-width">
</head>
<body>
    <div id="dataguard"></div>
    <script src="https://scripts.consentric.io/capture-point.min.js"></script>
    <script>
        window.addEventListener("load", () => {
            window.webkit.messageHandlers.loadedMessageHandler.postMessage(["Loaded", "true"]);
        });

        const init = ({ templateId, token }) => {
            StatefulWidget.load({
                id: 'dataguard',
                templateId,
                token,
                events: {
                    onSuccess: (response) => {
                        response.json().then((json) => {
                            window.webkit.messageHandlers.widgetMessageHandler.postMessage(["Success", JSON.stringify(json)]);
                        });
                    },
                    onFailure: (error, request) => {
                        window.webkit.messageHandlers.widgetMessageHandler.postMessage(["Failure", JSON.stringify({request, error})]);
                    },
                },
                consentricLogo: false,
            });
        }
    </script>
    <style>
        .mld-pc-minimise, .mld-pc-button--cancel {
            display: none;
        }
        .mld-pc-app-show {
            position: relative;
            border: none;
            box-shadow: none;
            max-height: 100%;
            min-height: 100%;
            padding: 0;
        }
        .mld-pc-app__header {
            padding: 0;
        }
    </style>
</body>

Step 2: Setting Up the ViewController

Next, load the index.html file into a WKWebView within a ViewController. This example shows a standard ViewController setup that renders the widget and handles communication between the WebView and the native app.

import UIKit
import WebKit

class DataGuardViewController: UIViewController, WKUIDelegate {
    
    var webView: WKWebView!
    
    override func loadView() {
        let widgetMessageHandler = WidgetMessageHandler()
        let webConfiguration = WKWebViewConfiguration()
        webConfiguration.preferences.javaScriptEnabled = true
        webConfiguration.userContentController.add(widgetMessageHandler, name: "widgetMessageHandler")
        webConfiguration.userContentController.add(self, name: "loadedMessageHandler")
        webView = WKWebView(frame: .zero, configuration: webConfiguration)
        webView.uiDelegate = self
        view = webView
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        if let htmlFile = Bundle.main.path(forResource: "index", ofType: "html"),
           let html = try? String(contentsOfFile: htmlFile, encoding: .utf8) {
            webView.loadHTMLString(html, baseURL: nil)
        }
    }
    
    func handleInit(result: Any?, error: Error?) {
        print(result ?? "No result")
        print(error ?? "No error")
    }
    
    func initWidget(templateId: String, token: String) {
        webView.evaluateJavaScript(
            """
            init({
                templateId:'\(templateId)',
                token:'\(token)'
            });
            """,
            completionHandler: handleInit(result:error:)
        )
    }
}

extension DataGuardViewController: WKScriptMessageHandler {
    func userContentController(
        _ userContentController: WKUserContentController,
        didReceive message: WKScriptMessage
    ) {
        if message.name == "loadedMessageHandler" {
            initWidget(
                templateId: "{{INSERT TEMPLATE ID HERE}}", 
                token: "{{INSERT ACCESS TOKEN HERE}}"
            )
        }
    }
}

Explanation:

  • ViewController Setup: This ViewController creates a WKWebView with JavaScript enabled and loads the index.html file created earlier.
  • Script Message Handling: The WKScriptMessageHandler interface allows the WebView to communicate with the native app. It listens for the "loadedMessageHandler" event to initialise the widget with the necessary templateId and token.

Step 3: Handling Widget Data

To handle the success and failure events from the widget, you can create a custom message handler class. This allows the app to respond to these events, such as displaying success messages or handling errors.

import WebKit
import Foundation

class WidgetMessageHandler: NSObject, WKScriptMessageHandler {
    func userContentController(_ userContentController: WKUserContentController,
                               didReceive message: WKScriptMessage) {
        if message.name == "widgetMessageHandler" {
            let json = message.body as! [String]
            switch json[0] {
            case "Success":
                // Handle success
                break
            case "Failure":
                // Handle failure
                break
            default:
                // Handle unexpected cases
                print("Unexpected message: \(json[0])")
                break
            }
        }
    }
}

Explanation:

  • Message Handling: The message structure follows a convention where the first element indicates the outcome ("Success" or "Failure"), and the second element contains metadata (e.g., a stringified JSON object). This setup allows you to handle different outcomes appropriately.

Summary

By following these steps, you can effectively integrate the DataGuard Manage Widget into your iOS app using a WKWebView. This approach provides a secure and responsive interface for managing user consent and preferences, while allowing your app to interact with the widget's data and events.