Skip to content

PUDO INTEGRATION iOS/APPLE

Arvato PUDO Widget Version 2.0.0


This document provides instructions on how to integrate the PUDO web component into an iOS mobile application using WKWebView in SwiftUI. The integration allows communication between the web component and the native iOS app through JavaScript message handlers.

⚠️️ Important: Geolocation Limitation: Getting the user's current geolocation is only supported in web browsers and is not available in iOS or Android WebView integrations. If the web component relies on the user's current position, you will need to implement a native geolocation solution and pass the coordinates to the web component with the search attribute.

PREREQUISITES

  • iOS application using SwiftUI.
  • Internet access to load the web component bundle.
  • A valid CLIENT-ID and BASE-URL for the PUDO web service.

IMPLEMENTATION DETAILS

1. Create the PUDOWebView Component

The PUDOWebView struct implements UIViewRepresentable to wrap a WKWebView inside SwiftUI.

import SwiftUI
import WebKit

struct PUDOWebView: UIViewRepresentable {
    let bundleJSURL = "https://<CLIENT-ID>.pudo.cxc.arvato-scs.digital/bundle.js"
    let baseURL = "https://<BASE-URL>"

    func makeUIView(context: Context) -> WKWebView {
        let userContentController = WKUserContentController()
        userContentController.add(context.coordinator, name: "onClose")
        userContentController.add(context.coordinator, name: "onSelectPoint")

        let webViewConfiguration = WKWebViewConfiguration()
        webViewConfiguration.userContentController = userContentController

        let wkwebView = WKWebView(frame: .zero, configuration: webViewConfiguration)
        wkwebView.navigationDelegate = context.coordinator

        // Load the initial HTML content
        wkwebView.loadHTMLString(htmlContent, baseURL: URL(string: baseURL)!)

        return wkwebView
    }

    func updateUIView(_ uiView: WKWebView, context: Context) {
        // No updates needed
    }

    func makeCoordinator() -> Coordinator {
        return Coordinator(self)
    }
}

2. Handling WebView Events

The Coordinator class manages communication between the WKWebView and the native app.

class Coordinator: NSObject, WKNavigationDelegate, WKScriptMessageHandler {
    var parent: PUDOWebView

    init(_ parent: PUDOWebView) {
        self.parent = parent
    }

    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        switch message.name {
        case "onClose":
            print("Close Callback Triggered")
        case "onSelectPoint":
            let point = message.body
            print("Point received: \(point)")
        default:
            break
        }
    }

    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        let script = """
        var script = document.createElement('script');
        script.src = '\(parent.bundleJSURL)';
        script.type = 'text/javascript';
        script.onload = function() {
            window.CXCPudo.open({
                language: '<LANGUAGE>',
                country: '<COUNTRY>',
                ismobileapp: 'true',
                onClose: () => {
                    window.webkit.messageHandlers.onClose.postMessage(null);
                },
                onSelectPoint: (point) => {
                    window.webkit.messageHandlers.onSelectPoint.postMessage(JSON.stringify(point));
                }
            })
        };
        document.head.appendChild(script);
        """

        webView.evaluateJavaScript(script) { result, error in
            if let error = error {
                print("JavaScript injection error: \(error.localizedDescription)")
            } else {
                print("JavaScript injected successfully")
            }
        }
    }
}

3. HTML Content Used in the WebView

The WKWebView loads a simple HTML template as the base structure.

private let htmlContent = """
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>PUDO Finder iOS Example</title>
</head>
<body>
</body>
</html>
"""

KEY FEATURES

  • Dynamic JavaScript Injection: Loads the PUDO web component script dynamically into the WKWebView.
  • Native-to-Web Communication: Uses WKScriptMessageHandler to listen for JavaScript events (onClose and onSelectPoint).
  • SwiftUI Integration: Wraps WKWebView in UIViewRepresentable for use in SwiftUI.

USAGE IN SWIFTUI VIEW

You can embed the PUDOWebView inside any SwiftUI view as follows:

struct ContentView: View {
    var body: some View {
        PUDOWebView()
            .edgesIgnoringSafeArea(.all)
    }
}