Saltar al contenido principal

iOS nativo (Swift)

Integra FaceGuard en aplicaciones iOS nativas usando WKWebView.

Configuración

Añade NSCameraUsageDescription a tu Info.plist:

Info.plist
<key>NSCameraUsageDescription</key>
<string>FaceGuard necesita acceso a la cámara para la verificación facial</string>

Implementación

FaceGuardViewController.swift
import WebKit

class FaceGuardViewController: UIViewController, WKScriptMessageHandler {
private var webView: WKWebView!

func startVerification(token: String) {
let config = WKWebViewConfiguration()
config.allowsInlineMediaPlayback = true
config.mediaTypesRequiringUserActionForPlayback = []

// Escuchar eventos postMessage
config.userContentController.add(self, name: "surtHandler")

// Inyectar puente: reenviar postMessage al manejador nativo
let script = WKUserScript(
source: """
window.addEventListener('message', function(e) {
if (e.data && (e.data.type === 'surt:ready' || e.data.action === 'close')) {
window.webkit.messageHandlers.surtHandler.postMessage(JSON.stringify(e.data));
}
});
""",
injectionTime: .atDocumentStart,
forMainFrameOnly: false
)
config.userContentController.addUserScript(script)

webView = WKWebView(frame: view.bounds, configuration: config)
webView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
view.addSubview(webView)

let url = URL(string: "https://faceguard.surt.com/intro?token=\(token)")!
webView.load(URLRequest(url: url))
}

func userContentController(
_ controller: WKUserContentController,
didReceive message: WKScriptMessage
) {
guard let body = message.body as? String,
let data = body.data(using: .utf8),
let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any]
else { return }

if let action = json["action"] as? String, action == "close" {
let reason = json["reason"] as? String ?? ""
let confidence = json["confidence"] as? Double ?? 0

switch reason {
case "approved", "bypass_active":
handleApproved(confidence: confidence)
case "rejected":
handleRejected(confidence: confidence)
case "canceled":
handleCanceled()
case "error", "no_base_photo":
handleError(message: json["error"] as? String ?? reason)
default:
break
}
}
}

func handleApproved(confidence: Double) { /* Conceder acceso */ }
func handleRejected(confidence: Double) { /* Denegar acceso */ }
func handleCanceled() { /* Usuario cerró */ }
func handleError(message: String) { /* Mostrar error */ }
}

Cómo funciona el puente

WKWebView no recibe de forma nativa eventos postMessage de iframes. El script JavaScript inyectado escucha los eventos message y los reenvía al WKScriptMessageHandler nativo mediante window.webkit.messageHandlers.

Áreas seguras

Usa Auto Layout con safeAreaLayoutGuide para evitar el notch y el indicador de inicio.